WebSocket客户端如何知道一条消息已被完全读取?

I used do it like:

    ...
    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
        }
    }

This has a bug: if the message's length is exactly 512 or 1024 or 2048... the loop never breaks; it will be stuck at ws.Read() and wait without throwing io.EOF.

Afterwards I observed that ws.Len() is always longer than the messages's length by 4.

I rewrote the code as:

    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
        }
    }

This way is okay.

But the number 4 is a magic code.

Is there a way to find the message's max length?

Some friends suggest separating the message packet, but I think WebSocket should not consider packet stucking or separating.

What is the most proper way for a WebSocket client to read a message?

It looks like you are using the golang.org/x/net/websocket package. It's not possible to reliably detect message boundaries using that package's Read method.

To fix, use websocket.Message to read messages.

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

Note that the golang.org/x/net/websocket documentation says:

This package currently lacks some features found in an alternative and more actively maintained WebSocket package:

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

The Gorilla documentation and examples show how to read messages.