websocket 是否保证单条消息的完整性?我应该为 websocket 消息实现自己的 header 吗?
Does websocket guarantee the completeness of a single message? Should I implement my own header for websocket messages?
我正在用 C++(使用 boost-beast)为 web-application 编写后端,而 front-end 可能会使用 socket.io。所以这个问题既适用于实现,也适用于 websocket 标准中是否有某些东西可以回答我的问题。
我不确定要采取什么预防措施来保证消息的完整性。假设客户端发送一条 100 字节长的消息,并且 boost::beast 将带有 async_read
的消息读取到 multi_buffer
。我能保证收到全部 100 个字节吗?大概。但是如果消息是 1 MB 怎么办?
为什么我觉得这个问题很重要?因为这决定了我的通信协议要简单到什么程度。如果只发送和接收完整的消息,那么我不必实现带有 header 的 middle-ware 协议来确定消息的大小(这通常是 TCP 所必需的,但是在某些消息传递库(如 ZeroMQ)中不是必需的)。但是,如果不能保证消息在到达时是完整的,那么我应该实施一个协议来获取消息大小。类似(尽可能简单):包含消息大小 + 消息的 6 个字节。然后我将其作为 FIFO queue 读取以处理消息的大小然后读取消息。
我是不是用错了 websocket 的方式?请指教
是的,这个问题很重要。
幸运的是,答案很简单:websocket 不是像 TCP 这样基于流的协议,它是基于消息的。
RFC 包含下图
+-+-+-+-+-------+-+-------------+-------------------------------+
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-------+-+-------------+-------------------------------+
|F|R|R|R| opcode|M| Payload len | Extended payload length |
|I|S|S|S| (4) |A| (7) | (16/64) |
|N|V|V|V| |S| | (if payload len==126/127) |
| |1|2|3| |K| | |
+-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - +
| Extended payload length continued, if payload len == 127 |
+ - - - - - - - - - - - - - - - +-------------------------------+
| | Masking-key, if MASK set to 1 |
+-------------------------------+-------------------------------+
| Masking-key (continued) | Payload Data |
+-------------------------------- - - - - - - - - - - - - - - - +
: Payload Data continued ... :
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
| Payload Data continued ... |
+---------------------------------------------------------------+
所以框架是 websocket 协议的一部分。如果您想了解它的详细信息,我认为这看起来像是一个很好的背景资料:http://lucumr.pocoo.org/2012/9/24/websockets-101/
但是,在实践中,您会使用更高级别的 Websockets 库,并且只使用它。
我正在用 C++(使用 boost-beast)为 web-application 编写后端,而 front-end 可能会使用 socket.io。所以这个问题既适用于实现,也适用于 websocket 标准中是否有某些东西可以回答我的问题。
我不确定要采取什么预防措施来保证消息的完整性。假设客户端发送一条 100 字节长的消息,并且 boost::beast 将带有 async_read
的消息读取到 multi_buffer
。我能保证收到全部 100 个字节吗?大概。但是如果消息是 1 MB 怎么办?
为什么我觉得这个问题很重要?因为这决定了我的通信协议要简单到什么程度。如果只发送和接收完整的消息,那么我不必实现带有 header 的 middle-ware 协议来确定消息的大小(这通常是 TCP 所必需的,但是在某些消息传递库(如 ZeroMQ)中不是必需的)。但是,如果不能保证消息在到达时是完整的,那么我应该实施一个协议来获取消息大小。类似(尽可能简单):包含消息大小 + 消息的 6 个字节。然后我将其作为 FIFO queue 读取以处理消息的大小然后读取消息。
我是不是用错了 websocket 的方式?请指教
是的,这个问题很重要。
幸运的是,答案很简单:websocket 不是像 TCP 这样基于流的协议,它是基于消息的。
RFC 包含下图
+-+-+-+-+-------+-+-------------+-------------------------------+
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-------+-+-------------+-------------------------------+
|F|R|R|R| opcode|M| Payload len | Extended payload length |
|I|S|S|S| (4) |A| (7) | (16/64) |
|N|V|V|V| |S| | (if payload len==126/127) |
| |1|2|3| |K| | |
+-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - +
| Extended payload length continued, if payload len == 127 |
+ - - - - - - - - - - - - - - - +-------------------------------+
| | Masking-key, if MASK set to 1 |
+-------------------------------+-------------------------------+
| Masking-key (continued) | Payload Data |
+-------------------------------- - - - - - - - - - - - - - - - +
: Payload Data continued ... :
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
| Payload Data continued ... |
+---------------------------------------------------------------+
所以框架是 websocket 协议的一部分。如果您想了解它的详细信息,我认为这看起来像是一个很好的背景资料:http://lucumr.pocoo.org/2012/9/24/websockets-101/
但是,在实践中,您会使用更高级别的 Websockets 库,并且只使用它。