[INet] WebSocket 数据收发的详细过程
WebSocket 和 HTTP 相似,只是一个应用层协议,对下层透明,所以不涉及 TCP/IP。
由于浏览器支持了 WebSocket,所以在用 JS 写客户端的时候,是无需考虑数据的编码解码的。
以下主要针对服务器端而言。
[ 接收数据,需要做的是解码,即 decode ]
要接收WebSocket数据,一个端点(endpoint)要监听底层网络连接。
进来的数据必须作为WebSocket帧(frame)解析。https://tools.ietf.org/html/rfc6455#section-5.2
如果接收到控制帧(control frame),这个帧必须被处理。https://tools.ietf.org/html/rfc6455#section-5.5
接收到数据帧的时候,https://tools.ietf.org/html/rfc6455#section-5.6
端点(endpoint)必须把数据的 /type/ 作为已定义的 opcode(frame-opcode) 解释。https://tools.ietf.org/html/rfc6455#section-5.2
帧中的应用层数据(Application data)在消息的 /data/ 中定义。
如果帧包含一个未拆分的消息(unfragmented message),https://tools.ietf.org/html/rfc6455#section-5.4
它是在说一个包含类型 /type/ 和数据 /data/ 的WebSocket消息已被接收。
如果帧是被拆分消息(fragmented message)的一部分,应用层数据(Application data)随后的数据帧被连接起来而形成数据。
当最后一个片段(fragment)作为 FIN 比特(frame-fin)标示被接收,
说明WebSocket消息已经接收了数据 /data/(包括由片段组成的应用层数据)和类型 /type/ (碎片消息的第一帧)。
后来的数据帧必须被作为新的WebSocket解释。
扩展(extensions)可能改变数据如何读取的语义,https://tools.ietf.org/html/rfc6455#section-9
特别是包括 - 什么构成消息的边界。
在一个有效载荷(payload)中,扩展(extensions)为了在应用层数据前面添加扩展数据(extension data),可能也修改应用层数据(通过压缩它)。
服务器必须移除从客户端接收数据帧的掩码(masking)。https://tools.ietf.org/html/rfc6455#section-5.3
[ 发送数据,需要做的是编码,即 encode ]
要在一个WebSocket连接上发送包含 /data/ 的WebSocket消息,端点(endpoint)必须执行如下步骤。
1.端点(endpoint)必须保证WebSocket连接是 OPEN 状态(握手操作之后)。如果在任何端点上,WebSocket连接状态改变了,端点必须终止以下步骤。
2.端点必须封装 /data/ 到WebSocket帧中。https://tools.ietf.org/html/rfc6455#section-5.2
3.第一个数据帧的 opcode(frame-opcode)包含的数据必须 针对数据被接收者解释为文本数据或二进制数据 来设置为合适的值。https://tools.ietf.org/html/rfc6455#section-5.2
4.包含数据的最后帧FIN比特(frame-fin),必须被设置为1。https://tools.ietf.org/html/rfc6455#section-5.2
5.如果数据正在被客户端发送,帧必须被掩码。https://tools.ietf.org/html/rfc6455#section-5.3
6.如果针对WebSocket连接的扩展已经议定,额外的考虑因素可以按照这些扩展的定义来应用。https://tools.ietf.org/html/rfc6455#section-9
7.已形成的帧必须在底层网络连接上传输。
相信你看明白了这个流程是一个过程概念阐述,实现需要遵照 section-5 的解释来 coding,而且只要实现功能,方式没有限制。
参考rfc:https://tools.ietf.org/html/rfc6455#section-6
PHP实现:https://github.com/phvia/via/blob/develop/Protocol/WebSocket.php