WebSockets协议与HTTP

有很多关于WebSocket和HTTP的博客和讨论,许多开发人员和网站强烈支持WebSocket,但我仍然不明白为什么

例如(WebSocket爱好者的参数):

HTML5WebSockets代表了Web通信的下一个发展——一个全双工双向通信通道,通过Web上的单个套接字进行操作。
( http://www.websocket.org/quantum.html )

HTTP支持流式传输:请求正文流式传输(您在上载大文件时使用它)和响应正文流式传输

在与WebSocket建立连接的过程中,客户端和服务器每帧交换数据,每个帧交换2个字节,而在进行连续轮询时,交换的HTTP头为8KB

为什么这2个字节不包括TCP和低于TCP协议的开销

GET/about.html HTTP/1.1
主持人:example.org

这是约48字节的HTTP头

HTTP分块编码-https://en.wikipedia.org/wiki/Chunked_transfer_encoding :

23
这是第一个区块中的数据
1A
这是第二个
3.
骗局
8.
序列
0
  • 因此,每个块的开销不大

而且,这两个协议都是通过TCP工作的,所以所有与长寿命连接有关的TCP问题仍然存在

问题:

  1. 为什么WebSockets协议更好
  2. 为什么要实现它而不是更新HTTP协议

1)为什么WebSockets协议更好?

WebSockets更适合于涉及低延迟通信的情况,特别是对于客户端到服务器消息的低延迟。对于服务器到客户端的数据,使用长时间保持的连接和分块传输可以获得相当低的延迟。但是,这对客户端到服务器的延迟没有帮助,这需要为每个客户端到服务器消息建立新的连接

对于现实世界中的HTTP浏览器连接,您的48字节HTTP握手并不现实,因为在现实世界中,通常有几千字节的数据作为请求的一部分(在两个方向上)发送,包括许多头和cookie数据。以下是使用Chrome的请求/响应示例:

请求示例(2800字节包括cookie数据,490字节没有cookie数据):

GET/HTTP/1.1
主持人:www.cnn.com
连接:保持活力
缓存控制:没有缓存
Pragma:没有缓存
接受:text/html、application/xhtml+xml、application/xml;q=0.9,*/*;q=0.8
用户代理:Mozilla/5.0(X11;Linux x86_64)AppleWebKit/537.17(KHTML,类似Gecko)Chrome/24.0.1312.68 Safari/537.17
接受编码:gzip、deflate、sdch
接受语言:en-US,en;q=0.8
接受字符集:ISO-8859-1,utf-8;q=0.7,*;q=0.3
Cookie:[[2428字节的Cookie数据]]]

响应示例(355字节):

HTTP/1.1 200正常
服务器:nginx
日期:2013年2月13日星期三18:56:27 GMT
内容类型:text/html
传输编码:分块
连接:保持活力
设置Cookie:CG=US:TX:Arlington;路径=/
最后修改:2013年2月13日星期三18:55:22 GMT
改变:接受编码
缓存控制:最大年龄=60,专用
过期时间:2013年2月13日星期三18:56:54 GMT
内容编码:gzip

HTTP和WebSocket都有大小相等的初始连接握手,但对于WebSocket连接,初始握手只执行一次,然后小消息的开销只有6字节(2字节用于头,4字节用于掩码值)。延迟开销并不是来自于头的大小,而是来自于解析/处理/存储这些头的逻辑。此外,TCP连接设置延迟可能比每个请求的大小或处理时间更大

2)为什么要实施它而不是更新HTTP协议?

人们正在努力重新设计HTTP协议,以实现更好的性能和更低的延迟,如SPDY、HTTP 2.0和QUIC。这将改善正常HTTP请求的情况,但WebSockets和/或WebRTC DataChannel的客户端到服务器数据传输延迟可能仍低于HTTP协议(或者它将在非常类似WebSockets的模式下使用)

更新

下面是一个考虑web协议的框架:

  • TCP:低层、双向、全双工和有保证的顺序传输层。不支持浏览器(通过插件/闪存除外)
  • HTTP 1.0:在TCP上分层的请求-响应传输协议。客户端发出一个完整请求,服务器给出一个完整响应,然后连接关闭。请求方法(GET、POST、HEAD)对于服务器上的资源具有特定的事务意义
  • HTTP 1.1:保持HTTP 1.0的请求-响应特性,但允许连接保持打开状态,以处理多个完整请求/完整响应(每个请求一个响应)。请求和响应中仍有完整的头,但连接被重新使用且未关闭。HTTP1.1还添加了一些额外的请求方法(选项、PUT、DELETE、TRACE、CONNECT),这些方法也具有特定的事务含义。但是,正如在HTTP 2.0草案的介绍中所指出的,HTTP 1.1管道并没有广泛部署,因此这极大地限制了HTTP 1.1解决浏览器和服务器之间延迟的实用性
  • 长投票:有点“a”;“黑客”;到HTTP(1.0或1.1),其中服务器不会立即响应(或仅使用头部分响应)客户端请求。服务器响应后,客户机立即发送一个新请求(如果通过HTTP 1.1,则使用相同的连接)
  • HTTP流传输:允许服务器向单个客户端请求发送多个响应的多种技术(多部分/分块响应)。W3C正在将其标准化,因为服务器使用文本/事件流MIME类型发送事件。浏览器API(相当类似于WebSocket API)称为EventSourceAPI
  • Comet/server push:这是一个总括术语,包括长轮询和HTTP流。Comet库通常支持多种技术,以尝试最大化跨浏览器和跨服务器支持
  • WebSocket:一种基于TCP的传输层,使用HTTP友好的升级握手。与TCP(流式传输)不同,WebSockets是一种基于消息的传输:消息在传输到应用程序之前在线路上进行分隔并完全重新组装。WebSocket连接是双向、全双工和长寿命的。在初始握手请求/响应之后,没有事务语义,每个消息的开销非常小。客户端和服务器可以随时发送消息,并且必须异步处理消息接收
  • SPDY:谷歌发起的一项提案,旨在使用更高效的有线协议扩展HTTP,但保留所有HTTP语义(请求/响应、cookie、编码)。SPDY引入了一种新的帧格式(带有长度前缀帧),并指定了一种将HTTP请求/响应对分层到新帧层的方法。建立连接后,可以压缩标头并发送新标头。在浏览器和服务器中有SPDY的真实实现
  • HTTP2.0:与SPDY有类似的目标:减少HTTP延迟和开销,同时保留HTTP语义。当前草案源于SPDY,定义了一个升级握手和数据帧,与WebSocket握手和帧标准非常相似。另一个HTTP 2.0草案提案(httpbis speed mobility)实际上将WebSocket用于传输层,并将SPDY多路复用和HTTP映射添加为WebSocket扩展(WebSocket扩展在握手过程中协商)
  • WebRTC/CU WebRTC:允许浏览器之间的点对点连接的建议。这可能会降低平均和最大延迟通信,因为底层传输是SDP/数据报,而不是TCP。这允许无序交付数据包/消息,从而避免因丢弃的数据包延迟所有后续数据包的交付而导致的TCP延迟峰值问题(以保证有序交付)
  • QUIC:是一种实验性协议,旨在与TCP相比减少web延迟。从表面上看,QUIC与UDP上实现的TCP+TLS+SPDY非常相似。QUIC提供与HTTP/2相当的多路复用和流量控制,与TLS相当的安全性,与TCP相当的连接语义、可靠性和拥塞控制。因为TCP是在操作系统内核和中间件中实现的,所以对TCP进行重大更改几乎是不可能的。然而,由于QUIC是在UDP之上构建的,所以它没有这样的限制。QUIC针对HTTP/2语义进行了设计和优化

参考资料

发表评论