douhong4452 2019-03-05 07:03
浏览 485

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?

  • 写回答

1条回答 默认 最新

  • dsgk0386 2019-03-05 07:40
    关注

    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.

    评论

报告相同问题?

悬赏问题

  • ¥15 outlook无法配置成功
  • ¥15 Pwm双极模式H桥驱动控制电机
  • ¥30 这是哪个作者做的宝宝起名网站
  • ¥60 版本过低apk如何修改可以兼容新的安卓系统
  • ¥25 由IPR导致的DRIVER_POWER_STATE_FAILURE蓝屏
  • ¥50 有数据,怎么建立模型求影响全要素生产率的因素
  • ¥50 有数据,怎么用matlab求全要素生产率
  • ¥15 TI的insta-spin例程
  • ¥15 完成下列问题完成下列问题
  • ¥15 C#算法问题, 不知道怎么处理这个数据的转换