1)为什么WebSockets协议更好?
WebSockets 更适合涉及低延迟通信的情况,尤其是客户端到服务器消息的低延迟。对于服务器到客户端的数据,您可以使用长期连接和分块传输获得相当低的延迟。但是,这对客户端到服务器的延迟没有帮助,这需要为每个客户端到服务器的消息建立新的连接。
您的 48 字节 HTTP 握手对于现实世界的 HTTP 浏览器连接是不现实的,因为请求通常会发送几千字节的数据作为请求的一部分(双向),包括许多标头和 cookie 数据。以下是使用 Chrome 的请求/响应示例:
示例请求(2800 字节包括 cookie 数据,490 字节不包括 cookie 数据):
GET / HTTP/1.1
Host: www.cnn.com
Connection: keep-alive
Cache-Control: no-cache
Pragma: no-cache
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.17 (KHTML, like Gecko) Chrome/24.0.1312.68 Safari/537.17
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
Cookie: [[[2428 byte of cookie data]]]
响应示例(355 字节):
HTTP/1.1 200 OK
Server: nginx
Date: Wed, 13 Feb 2013 18:56:27 GMT
Content-Type: text/html
Transfer-Encoding: chunked
Connection: keep-alive
Set-Cookie: CG=US:TX:Arlington; path=/
Last-Modified: Wed, 13 Feb 2013 18:55:22 GMT
Vary: Accept-Encoding
Cache-Control: max-age=60, private
Expires: Wed, 13 Feb 2013 18:56:54 GMT
Content-Encoding: gzip
HTTP 和 WebSockets 都具有相同大小的初始连接握手,但是对于 WebSocket 连接,初始握手执行一次,然后小消息只有 6 个字节的开销(2 个用于标头,4 个用于掩码值)。延迟开销不是来自标头的大小,而是来自解析/处理/存储这些标头的逻辑。此外,TCP 连接建立延迟可能是比每个请求的大小或处理时间更大的因素。
2) 为什么要实现它而不是更新 HTTP 协议?
有人努力重新设计 HTTP 协议以实现更好的性能和更低的延迟,例如SPDY、HTTP 2.0和QUIC。这将改善普通 HTTP 请求的情况,但 WebSockets 和/或 WebRTC DataChannel 的客户端到服务器数据传输的延迟很可能仍然低于 HTTP 协议(或者它将用于看起来很像 WebSockets 的模式无论如何)。
更新:
这是一个思考 Web 协议的框架:
TCP:低层、双向、全双工、保证顺序的传输层。不支持浏览器(通过插件/Flash 除外)。
HTTP 1.0:基于 TCP 的请求-响应传输协议。客户端发出一个完整的请求,服务器给出一个完整的响应,然后关闭连接。请求方法(GET、POST、HEAD)对服务器上的资源具有特定的事务意义。
HTTP 1.1:保持 HTTP 1.0 的请求-响应特性,但允许连接保持打开状态以接收多个完整请求/完整响应(每个请求一个响应)。请求和响应中仍有完整的标头,但连接被重用且未关闭。HTTP 1.1 还添加了一些额外的请求方法(OPTIONS、PUT、DELETE、TRACE、CONNECT),它们也具有特定的事务含义。然而,正如 HTTP 2.0 草案提案的介绍中所指出的,HTTP 1.1 流水线并未广泛部署,因此这极大地限制了 HTTP 1.1 在解决浏览器和服务器之间的延迟方面的实用性。
长轮询:对 HTTP(1.0 或 1.1)的一种“破解”,其中服务器不会立即响应(或仅使用标头部分响应)客户端请求。在服务器响应之后,客户端立即发送一个新请求(如果通过 HTTP 1.1,则使用相同的连接)。
HTTP 流式传输:允许服务器向单个客户端请求发送多个响应的多种技术(多部分/分块响应)。W3C 正在将其标准化为使用MIME 类型的服务器发送事件。text/event-stream
浏览器 API(与 WebSocket API 非常相似)称为 EventSource API。
Comet/服务器推送:这是一个涵盖长轮询和 HTTP 流的总称。Comet 库通常支持多种技术来尝试和最大化跨浏览器和跨服务器支持。
WebSockets:建立在 TCP 上的传输层,使用 HTTP 友好的升级握手。与作为流传输的 TCP 不同,WebSockets 是基于消息的传输:消息在线路上进行分隔,并在交付给应用程序之前完整地重新组装。WebSocket 连接是双向的、全双工的和长寿命的。在初始握手请求/响应之后,没有事务语义,并且每条消息的开销很小。客户端和服务器可以随时发送消息,并且必须异步处理消息接收。
SPDY:Google 发起的一项提议,使用更有效的有线协议扩展 HTTP,但保留所有 HTTP 语义(请求/响应、cookie、编码)。SPDY 引入了一种新的帧格式(以长度为前缀的帧),并指定了一种将 HTTP 请求/响应对分层到新的帧层上的方法。可以压缩标头,并且可以在建立连接后发送新的标头。在浏览器和服务器中有 SPDY 的真实实现。
HTTP 2.0:与 SPDY 具有相似的目标:减少 HTTP 延迟和开销,同时保留 HTTP 语义。当前草案源自 SPDY,定义了升级握手和数据帧,与用于握手和帧的 WebSocket 标准非常相似。另一个 HTTP 2.0 草案提案 (httpbis-speed-mobility) 实际上将 WebSockets 用于传输层,并将 SPDY 多路复用和 HTTP 映射添加为 WebSocket 扩展(WebSocket 扩展在握手期间协商)。
WebRTC/CU-WebRTC:允许浏览器之间的点对点连接的建议。这可以实现更低的平均和最大延迟通信,因为底层传输是 SDP/数据报而不是 TCP。这允许数据包/消息的无序传递,从而避免了由丢弃的数据包引起的延迟峰值的 TCP 问题,这会延迟所有后续数据包的传递(以保证按顺序传递)。
QUIC:是一种实验性协议,旨在减少 TCP 的网络延迟。从表面上看,QUIC 与在 UDP 上实现的 TCP+TLS+SPDY 非常相似。QUIC 提供相当于 HTTP/2 的多路复用和流量控制,相当于 TLS 的安全性,以及相当于 TCP 的连接语义、可靠性和拥塞控制。由于 TCP 是在操作系统内核和中间盒固件中实现的,因此对 TCP 进行重大更改几乎是不可能的。然而,由于 QUIC 是建立在 UDP 之上的,它没有这样的限制。QUIC 是针对 HTTP/2 语义设计和优化的。
参考资料:
HTTP:
服务器发送事件:
网络套接字:
SPDY:
HTTP 2.0:
WebRTC:
快速: