Web开发

首页 » 常识 » 诊断 » Web应用架构WebSocket协
TUhjnbcbe - 2020/12/5 1:40:00

由HyBi工作组开发的WebSocket有线协议(RFC)由两个高级组件组成:用于协商连接参数的开放HTTP握手和二进制消息帧机制,以实现低开销、基于消息的文本和二进制数据传输。

WebSocket协议试图在现有HTTP基础架构的上下文中解决现有双向HTTP技术的目标;因此,它被设计为在HTTP端口80和上工作……然而,这种设计并没有将WebSocket限制为HTTP,而且未来的实现可以在专用端口上使用更简单的握手,而无需重新发明整个协议。

----WebSocket协议RFC

WebSocket协议是一个功能完整的独立协议,可以在浏览器之外使用。尽管如此,它的主要应用程序是作为基于浏览器的应用程序的双向传输。

二进制框架层

客户端和服务器端WebSocket应用程序通过一个面向消息的API进行通信:发送方提供一个任意的UTF-8或二进制有效负载,当整个消息可用时,接收方被通知它的传递。为了实现这一点,WebSocket使用了自定义的二进制帧格式(图17-1),它将每个应用程序消息分解成一个或多个帧,将它们传输到目的地,重新组装它们,并在收到整个消息后通知接收者。

Figure17-1.WebSocketframe:2–14bytes+payload

Frame

通信的最小单位,每个单位包含一个可变长度的帧头和一个可携带全部或部分应用程序消息的有效负载。

Message

映射到逻辑应用程序消息的完整帧序列。

决定将应用程序消息分割成多个框架是由客户机和服务器框架代码的底层实现做出的。因此,应用程序仍然很高兴地不知道各个WebSocket帧或者帧是如何执行的。话虽如此,理解每个WebSocket帧在连线上是如何表示的要点仍然是有用的:

每个帧(FIN)的第一个比特表示该帧是否为消息的最后一个片段。一条消息可能只包含一帧。

操作码(4位)表示传输帧的类型:用于传输应用程序数据的文本(1)或二进制(2)或用于连接活性检查的控制帧,如连接关闭(8)、ping(9)和pong(10)。

掩码位指示负载是否被掩码(仅针对从客户机发送到服务器的消息)。

有效载荷长度用可变长度字段表示:如果0-,那么这就是有效载荷长度。如果是,那么下面的两个字节表示一个16位无符号整数,表示帧长度。如果是,那么下面的8个字节表示一个64位无符号整数,表示帧长度。

屏蔽键包含一个用于屏蔽有效负载的32位值。

有效负载包含应用程序数据和自定义扩展数据(如果客户端和服务器在建立连接时协商了扩展)。

所有客户端发起的帧的有效负载都使用帧头中指定的值来隐藏:这可以防止恶意脚本在客户端执行缓存中*攻击,攻击那些可能不理解WebSocket协议的中介。有关这次攻击的详细信息,请参考年W2SP上的"TalkingtoYourselfforFunandPro?t"。

因此,每个服务器发送的WebSocket帧都会产生2-10字节的帧开销。客户端还必须发送一个屏蔽密钥,这将在头文件中增加额外的4个字节,导致开销增加6-14个字节。没有其他元数据可用,例如头字段或关于有效负载的其他信息:所有WebSocket通信都是通过交换帧来执行的,这些帧将有效负载视为应用程序数据的不透明blob。

WebSocket多路复用和堆头阻塞(Head-of-LineBlocking)

WebSocket易受行头阻塞的影响:消息可以被分割成一个或多个帧,但是来自不同消息的帧不能交叉,因为在HTTP/2帧机制中没有等效的“流ID”;参见流、消息和帧)。

因此,一个大消息,即使被分割成多个WebSocket帧,也会阻止与其他消息相关联的帧的传递。如果您的应用程序交付的是对延迟敏感的数据,请注意每个消息的有效负载大小,并考虑将大消息拆分为多个应用程序消息!

核心WebSocket规范中缺乏多路复用也意味着每个WebSocket连接都需要一个专用的TCP连接,这可能成为HTTP/1的一个潜在问题。由于浏览器维护的每个源的连接数量有限而进行的部署;请参阅耗尽客户机和服务器资源。

从好的方面来看,由HyBi工作组开发的“WebSockets多路复用扩展”解决了后一个限制:

有了这个扩展,一个TCP连接可以通过封装带有通道ID标签的帧来提供多个虚拟WebSocket连接……这个多路复用扩展维护独立的逻辑通道,每个逻辑通道提供独立WebSocket连接的完全等价逻辑,包括单独的握手头。

--------------WebSocket多路复用(草案10)

有了这个扩展,多个WebSocket连接(通道)可以在同一个TCP连接上多路复用。然而,每个单独的通道仍然很容易被线头阻塞!因此,一种可能的解决方案是使用不同的通道或专用的TCP连接并行地多路传输多个消息。

最后,注意前面的扩展仅对HTTP/1是必要的。x连接。虽然目前还没有官方规范可以使用HTTP/2传输WebSocket帧,但是这样做会容易得多:HTTP/2有内置的流多路复用,通过在HTTP/2帧机制中封装WebSocket帧,可以在一个会话中传输多个WebSocket连接。

协议的扩展

WebSocket规范允许协议扩展:WebSocket协议的有线格式和语义可以通过新的操作码和数据字段进行扩展。虽然有些不寻常,但这是一个非常强大的特性,因为它允许客户端和服务器在基本的WebSocket框架层之上实现额外的功能,而不需要任何来自应用程序代码的干预或合作。

有一些WebSocket协议扩展的例子吗?负责WebSocket规范开发的HyBi工作组列出了两个正在开发中的官方扩展:

“WebSockets的多路复用扩展”

这个扩展为单独的逻辑WebSocket连接提供了一种共享底层传输连接的方法。

“WebSocket的压缩扩展”

一个用于创建WebSocket扩展的框架,为WebSocket协议添加压缩功能。

如前所述,每个WebSocket连接都需要一个专用的TCP连接,这是低效的。多路复用扩展通过为每个WebSocket帧增加一个额外的“通道ID”来允许多个虚拟的WebSocket通道共享一个TCP连接来解决这个问题。

类似地,基本的WebSocket规范没有为传输数据的压缩提供任何机制或规定:每一帧都携带由应用程序提供的有效负载数据。因此,虽然这对于优化的二进制数据结构来说不是问题,但这可能会导致高字节传输开销,除非应用程序实现了自己的数据压缩和解压缩逻辑。实际上,压缩扩展支持HTTP提供的等效传输编码协商。

要启用一个或多个扩展,客户机必须在初始升级握手时公布它们,服务器必须选择并确认在协商的连接的生命周期中将使用的扩展。作为一个实际的示例,现在让我们仔细看看升级顺序。

WebSocket多路复用和压缩在野外

到年中期,WebSocket多路复用还没有被任何流行的浏览器支持。类似地,对压缩的支持也很有限:谷歌Chrome和最新的WebKit浏览器可能会在服务器上发布一个“x-webkit-deflate-frame”扩展。然而,deflate-frame是基于一个过时的修订标准,并将在未来过时。

顾名思义,每帧都是逐帧压缩有效负载内容,这对于可能在多个帧之间分割的大消息不是最优的。因此,压缩扩展的最新版本已经切换到每消息压缩——这是一个好消息。坏消息是每条消息的压缩还处于试验阶段,目前还不能在任何流行的浏览器中使用。

因此,应用程序应该密切

1
查看完整版本: Web应用架构WebSocket协