Как клиент WebSocket узнает, что сообщение полностью прочитано? - PullRequest
0 голосов
/ 05 марта 2019

Я использовал это так:

    ...
    ws, err := websocket.Dial(url, "", origin)
    ...
    var buffer = make([]byte, 512)
    var rs = make([]byte, 0, 512)
L:
    for {
        m, err := ws.Read(buffer)
        if err != nil {
            if err == io.EOF {
                break L
            }
            fmt.Println(err.Error())
            return
        }
        rs = append(rs, buffer[:m]...)
        if m < 512 {
            break L
        }
    }

В этом есть ошибка: если длина сообщения ровно 512, или 1024, или 2048 ... цикл никогда не прерывается;он застрянет на ws.Read() и будет ждать, не выбрасывая io.EOF.

Впоследствии я заметил, что ws.Len() всегда длиннее, чем длина сообщения, на 4.

Я переписал код так:

    var buffer = make([]byte, 512)
    var rs = make([]byte, 0, 512)
    var sum = 0
L:
    for {
        m, err := ws.Read(buffer)
        if err != nil {
            if err == io.EOF {
                break L
            }
            fmt.Println(err.Error())
            return
        }
        rs = append(rs, buffer[:m]...)
        sum+=m
        if sum >= ws.Len()-4 {
            break L
        }
    }

Это нормально.

Но число 4 является магическим кодом.

Можно ли найти максимальную длину сообщения?

Некоторые друзья предлагают разделить пакет сообщения, но я думаю, что WebSocket не следует рассматривать блокирование или разделение пакета.

Какой самый подходящий способ для клиента WebSocket прочитать сообщение?

1 Ответ

0 голосов
/ 05 марта 2019

Похоже, вы используете пакет golang.org/x/net/websocket.Невозможно надежно определить границы сообщения, используя метод чтения этого пакета.

Чтобы исправить, используйте websocket.Message для чтения сообщений.

var msg string
err := websocket.Message.Receive(ws, &msg)
if err != nil {
  // handle error
}
// msg is the message

Обратите внимание, что в документации golang.org / x / net / websocket говорится:

В этом пакете в настоящее время отсутствуют некоторые функции, найденные в альтернативной версии.более активно поддерживаемый пакет WebSocket:

https://godoc.org/github.com/gorilla/websocket

Документация Gorilla и Примеры показывают, как читать сообщения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...