Page 274 - Web性能权威指南
P. 274
➍ 服务器选择的应用子协议
➎ 服务器选择的 WebSocket 扩展
所有兼容 RFC 6455 的 WebSocket 服务器都使用相同的算法计算客户端挑
战的答案:将 Sec-WebSocket-Key 的内容与标准定义的唯一 GUID 字符串
拼接起来,计算出 SHA1 散列值,结果是一个 base-64 编码的字符串,把
这个字符串发给客户端即可。
最低限度,成功的 WebSocket 握手必须是客户端发送协议版本和自动生成的挑战
值,服务器返回 101 HTTP 响应码(Switching Protocols)和散列形式的挑战答案,
确认选择的协议版本:
• 客户端必须发送 Sec-WebSocket-Version 和 Sec-WebSocket-Key;
• 服务器必须返回 Sec-WebSocket-Accept 确认协议;
• 客户端可以通过 Sec-WebSocket-Protocol 发送应用子协议列表;
• 服务器必须选择一个子协议并通过 Sec-WebSocket-Protocol 返回协议名;如果服
务器不支持任何一个协议,连接断开;
• 客户端可以通过 Sec-WebSocket-Extensions 发送协议扩展;
• 服务器可以通过 Sec-WebSocket-Extensions 确认一或多个扩展;如果服务器没有
返回扩展,则连接不支持扩展。
最后,前述握手完成后,如果握手成功,该连接就可以用作双向通信信道交换
WebSocket 消息。从此以后,客户端与服务器之间不会再发生 HTTP 通信,一切由
WebSocket 协议接管。
代理、中间设备与 WebSocket
实践中,考虑到安全和保密,很多用户都只开放有限的端口,通常只有 80
(HTTP)和 443(HTTPS)。正因为如此,WebSocket 协商是通过 HTTP Upgrade
流进行的,这样可以确保与现有网络策略及基础设施兼容。
不过,正如 4.1 节的“Web 代理、中间设备、TLS 与新协议”所说,很多现有的
HTTP 中间设备可能不理解新的 WebSocket 协议,而这可能导致各种问题:盲目
的连接升级、意外缓冲 WebSocket 帧、不明就里地修改内容、把 WebSocket 流量
误当作不完整的 HTTP 通信,等等。
WebSocket 的 Key 和 Accept 握手可以解决其中一些问题:这是服务器的一个安全
策略,而盲目“升级”连接的中间设备可能并不理解 WebSocket 协议。虽然这个
预防措施对某些代理可以解决问题,但对于那些“透明代理”还是不行,它们可
能会分析并意外地修改数据。
WebSocket | 263