在WebSockets中实现permessage-deflate

7

我在理解和实现WebSocket的permessage-deflate扩展方面遇到了问题。

目前为止,我已经在握手代码中添加了“Sec-WebSocket-Extensions:permessage-deflate”,看起来一切都很正常。

然而,当我从服务器(Node.js)向客户端(JS)发送“TEST”消息时,浏览器(Chrome和Firefox)似乎没有自己解压缩数据。

如何正确地使用permessage-deflate扩展实现数据压缩和解压缩?

请求头:

GET ws://localhost/ HTTP/1.1
Host: localhost
Connection: Upgrade
Pragma: no-cache
Cache-Control: no-cache
Upgrade: websocket
Origin: null
Sec-WebSocket-Version: 13
User-Agent: Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.152 Safari/537.36
Accept-Encoding: gzip, deflate, sdch
Accept-Language: nl-NL,nl;q=0.8,en-US;q=0.6,en;q=0.4
Sec-WebSocket-Key: X3RofjiYbzVR8zUPI5ZI6w==
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits
Sec-WebSocket-Protocol: Exodus_101

响应头:

HTTP/1.1 101 Web Socket Protocol Handshake
Upgrade: WebSocket
Connection: Upgrade
sec-websocket-accept: sFO1Id30BZe63QWcm894hnnb+Pg=
Sec-WebSocket-Protocol: Exodus_101
Sec-WebSocket-Extensions: permessage-deflate

复制并粘贴握手协商。 - vtortola
@vtortola 你好!我刚刚编辑了上面的帖子。我已经包含了头文件。 - user1491657
握手似乎没问题,你是如何压缩和解压缩的? - vtortola
我并不是这样想的,我认为当在头部添加permessage-deflate时,整个压缩和解压缩功能会自动发生。我的问题在于如何实现压缩和解压缩的理解。 - user1491657
嗯...你必须在node.js中启用某些东西或添加扩展,而不仅仅是返回一个头文件。 - vtortola
1个回答

8

服务器和客户端都可以使用握手期间协商的参数来对WebSocket数据消息的有效载荷数据部分进行逐条消息压缩。

permessage-deflate头用于在握手期间指示连接是否应使用压缩。

  1. 当客户端发送WebSocket请求时,如果客户端浏览器支持,则在WebSocket扩展头中发送permessage-deflate。服务器根据此标头判断客户端是否支持压缩。
  2. 如果服务器决定使用压缩,则会响应相同的标头,类似于ACK消息。客户端在接收到响应后根据服务器的响应决定是否压缩数据。

一旦服务器和客户端都决定使用压缩,它们必须分别使用deflate压缩技术对消息进行压缩。 即,您需要在创建WebSocket服务器时使用"perMessageDeflate"选项在服务器上启用压缩。 ws节点模块默认启用此功能。 ws模块会处理标头标志,因此您不需要显式设置它。

注意:Deflate使用LZ77和Huffman编码的组合来压缩数据。client_max_window_bits; server_max_window_bits=10标头标志用于设置LZ77算法使用的自定义缓冲区/“滑动窗口”,以减少内存开销。


1
一个小修正:ws节点模块支持permessage-deflate扩展,但默认情况下仅在客户端上启用它。服务器默认关闭它,并建议我们仅在代表性工作负载上测试后再打开它,因为它对CPU和内存都有重大影响。 - Pradeep Vairamani

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接