Page 270 - Web性能权威指南
P. 270

•   操作码(4 位)表示被传输帧的类型:传输应用数据时,是文本(1)还是二进制
                  (2);连接有效性检查时,是关闭(8)、呼叫(ping,9)还是回应(pong,10)。
                 •   掩码位表示净荷是否有掩码(只适用于客户端发送给服务器的消息)。
                 •   净荷长度由可变长度字段表示:
                      Œ  如果是 0~125,就是净荷长度;
                      Œ  如果是 126,则接下来 2 字节表示的 16 位无符号整数才是这一帧的长度;
                      Œ  如果是 127,则接下来 8 字节表示的 64 位无符号整数才是这一帧的长度。
                 •   掩码键包含 32 位值,用于给净荷加掩护。
                 •   净荷包含应用数据,如果客户端和服务器在建立连接时协商过,也可以包含自定
                   义的扩展数据。

                            所有客户端发送帧的净荷都要使用帧首部中指定的值加掩码,这样可以防
                            止客户端中运行的恶意脚本对不支持 WebSocket 的中间设备进行缓存投
                            毒攻击(cache poisoning attack)。要了解这种攻击的细节,请参考 W2SP
                            2011 的论文“Talking to Yourself for Fun and Profit”(http://w2spconf.com/
                            2011/papers/websocket.pdf)。

                 算下来,服务器发送的每个 WebSocket 帧会产生 2~10 字节的分帧开销。而客户端
                 必须发送掩码键,这又会增加 4 字节,结果就是 6~14 字节的开销。除此之外,没
                 有其他元数据(比如首部字段或其他关于净荷的信息):所有 WebSocket 通信都是
                 通过交换帧实现的,而帧将净荷视为不透明的应用数据块。



                                   WebSocket 的多路复用及队首阻塞
                   WebSocket 很容易发生队首阻塞的情况:消息可能会被分成一或多个帧,但不同
                   消息的帧不能交错发送,因为没有与 HTTP 2.0 分帧机制中“流 ID”对等的字段
                  (参见 12.3.2 节“流、消息和帧”)。
                   显然,如果一个大消息被分成多个 WebSocket 帧,就会阻塞其他消息的帧。如果
                   你的应用不容许有交付延迟,那可以小心控制每条消息的净荷大小,甚至可以考
                   虑把大消息拆分成多个小消息!

                   WebSocket 不支持多路复用,还意味着每个 WebSocket 连接都需要一个专门的
                   TCP 连接。对于 HTTP 1.x 而言,由于浏览器针对每个来源有连接数量限制,因此
                   可能会导致问题(参见 11.3 节中的“消耗客户端和服务器资源”)。

                   好 在,HyBi Working Group 正 着 手 制 定 的 新 的“Multiplexing Extension for
                   WebSockets”(WebSockets 多路复用扩展)会解决这个问题:






                                                                            WebSocket   |   259
   265   266   267   268   269   270   271   272   273   274   275