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
   269   270   271   272   273   274   275   276   277   278   279