问题描述
关于WebSocket和HTTP的博客和讨论很多,很多开发者和网站都大力提倡WebSockets,但我还是不明白为什么.
例如(WebSocket爱好者的争论):
HTML5 Web Sockets 代表了 Web 通信的下一个发展——全双工、双向通信通道,通过 Web 上的单个套接字运行.( http://www.websocket.org/quantum.html )
HTTP 支持流式传输:请求正文流式传输(您在上传大文件时使用它)和响应正文流式传输.
在与 WebSocket 建立连接期间,客户端和服务器每帧交换数据,每帧 2 个字节,而在进行连续轮询时,HTTP 标头为 8 KB.
为什么那 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 问题仍然存在.
问题:
- 为什么 WebSockets 协议更好?
- 为什么实施它而不是更新 HTTP 协议?
1) 为什么 WebSockets 协议更好?
WebSockets 更适合涉及低延迟通信的情况,尤其是客户端到服务器消息的低延迟.对于服务器到客户端的数据,您可以使用长期保持的连接和分块传输获得相当低的延迟.但是,这无助于解决客户端到服务器的延迟问题,因为这需要为每个客户端到服务器的消息建立新的连接.
您的 48 字节 HTTP 握手对于现实世界的 HTTP 浏览器连接来说是不现实的,在现实世界中,通常会有几千字节的数据作为请求的一部分(双向)发送,包括许多标头和 cookie 数据.以下是使用 Chrome 的请求/响应示例:
示例请求(2800 字节包括 cookie 数据,490 字节不包括 cookie 数据):
GET/HTTP/1.1主持人:www.cnn.com连接:保持连接缓存控制:无缓存编译指示:无缓存接受:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8用户代理:Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.17 (KHTML, like 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.3Cookie:[[[2428 字节的 cookie 数据]]]
示例响应(355 字节):
HTTP/1.1 200 OK服务器:nginx日期:2013 年 2 月 13 日,星期三 18:56:27 GMT内容类型:文本/html传输编码:分块连接:保持连接设置-Cookie:CG=US:TX:Arlington;路径=/最后修改时间:2013 年 2 月 13 日,星期三 18:55:22 GMT变化:接受编码缓存控制:max-age=60,私有到期时间:2013 年 2 月 13 日星期三 18:56:54 GMT内容编码:gzip
HTTP 和 WebSockets 都有相同大小的初始连接握手,但是对于 WebSocket 连接,初始握手执行一次,然后小消息只有 6 个字节的开销(2 个用于标头,4 个用于掩码值).延迟开销不是来自标头的大小,而是来自解析/处理/存储这些标头的逻辑.此外,TCP 连接建立延迟可能是比每个请求的大小或处理时间更大的因素.
2) 为什么实施它而不是更新 HTTP 协议?
正在努力重新设计 HTTP 协议以实现更好的性能和更低的延迟,例如 SPDY、HTTP 2.0 和 QUIC.这将改善正常 HTTP 请求的情况,但很可能 WebSockets 和/或 WebRTC DataChannel 的客户端到服务器数据传输的延迟仍然比 HTTP 协议低(或者它将以看起来很像 WebSockets 的模式使用反正).
更新:
这是一个思考网络协议的框架:
- 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 正在将其标准化为 Server-Sent Events 使用
text/event-流
MIME 类型.浏览器 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:
- 维基百科 HTTP 页面
- HTTP 相关草案/协议的 W3C 列表
- IETF HTTP/1.1 和 HTTP/2.0 草案列表
- 服务器发送的事件:
- W3C 服务器发送的事件/EventSource 候选推荐
- W3C 服务器发送的事件/事件源草案
- WebSockets:
- IETF RFC 6455 WebSockets 协议
- IETF RFC 6455 WebSocket 勘误表
- SPDY:
- IETF SPDY 草案
- HTTP 2.0:
- IETF HTTP 2.0 httpbis-http2 草案
- IETF HTTP 2.0 httpbis-speed-mobility 草案
- IETF httpbis-network-friendly 草案 - 一个旧的 HTTP 2.0 相关提案
- WebRTC:
- W3C WebRTC API 草案
- IETF WebRTC 草案列表
- IETF WebRTC 概述草案
- IETF WebRTC 数据通道草案
- Microsoft CU-WebRTC 提案起始页
- QUIC:
- QUIC Chrominum 项目
- IETF QUIC 草案
There are many blogs and discussions about WebSocket and HTTP, and many developers and sites strongly advocate WebSockets, but I still can not understand why.
for example (arguments of WebSocket lovers):
HTTP supports streaming: request body streaming(you are using it while uploading large files) and response body streaming.
Why do that 2 bytes not include TCP and under TCP protocols overhead?
GET /about.html HTTP/1.1
Host: example.org
This is ~48 bytes HTTP header.
HTTP chunked encoding - https://en.wikipedia.org/wiki/Chunked_transfer_encoding :
23
This is the data in the first chunk
1A
and this is the second one
3
con
8
sequence
0
- So, the overhead per each chunk is not big.
Also, both protocols work over TCP, so all TCP issues with long-live connections are still there.
Questions:
- Why is the WebSockets protocol better?
- Why was it implemented instead of updating the HTTP protocol?
1) Why is the WebSockets protocol better?
WebSockets is better for situations that involve low-latency communication especially for low latency for client to server messages. For server to client data you can get fairly low latency using long-held connections and chunked transfer. However, this doesn't help with client to server latency which requires a new connection to be established for each client to server message.
Your 48 byte HTTP handshake is not realistic for real-world HTTP browser connections where there is often several kilobytes of data sent as part of the request (in both directions) including many headers and cookie data. Here is an example of a request/response to using Chrome:
Example request (2800 bytes including cookie data, 490 bytes without cookie data):
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]]]
Example response (355 bytes):
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
Both HTTP and WebSockets have equivalent sized initial connection handshakes, but with a WebSocket connection the initial handshake is performed once and then small messages only have 6 bytes of overhead (2 for the header and 4 for the mask value). The latency overhead is not so much from the size of the headers, but from the logic to parse/handle/store those headers. In addition, the TCP connection setup latency is probably a bigger factor than the size or processing time for each request.
2) Why was it implemented instead of updating HTTP protocol?
There are efforts to re-engineer the HTTP protocol to achieve better performance and lower latency such as SPDY, HTTP 2.0 and QUIC. This will improve the situation for normal HTTP requests, but it is likely that WebSockets and/or WebRTC DataChannel will still have lower latency for client to server data transfer than HTTP protocol (or it will be used in a mode that looks a lot like WebSockets anyways).
Update:
Here is a framework for thinking about web protocols:
- TCP: low-level, bi-directional, full-duplex, and guaranteed order transport layer. No browser support (except via plugin/Flash).
- HTTP 1.0: request-response transport protocol layered on TCP. The client makes one full request, the server gives one full response, and then the connection is closed. The request methods (GET, POST, HEAD) have specific transactional meaning for resources on the server.
- HTTP 1.1: maintains the request-response nature of HTTP 1.0, but allows the connection to stay open for multiple full requests/full responses (one response per request). Still has full headers in the request and response but the connection is re-used and not closed. HTTP 1.1 also added some additional request methods (OPTIONS, PUT, DELETE, TRACE, CONNECT) which also have specific transactional meanings. However, as noted in the introduction to the HTTP 2.0 draft proposal, HTTP 1.1 pipelining is not widely deployed so this greatly limits the utility of HTTP 1.1 to solve latency between browsers and servers.
- Long-poll: sort of a "hack" to HTTP (either 1.0 or 1.1) where the server does not respond immediately (or only responds partially with headers) to the client request. After a server response, the client immediately sends a new request (using the same connection if over HTTP 1.1).
- HTTP streaming: a variety of techniques (multipart/chunked response) that allow the server to send more than one response to a single client request. The W3C is standardizing this as Server-Sent Events using a
text/event-stream
MIME type. The browser API (which is fairly similar to the WebSocket API) is called the EventSource API. - Comet/server push: this is an umbrella term that includes both long-poll and HTTP streaming. Comet libraries usually support multiple techniques to try and maximize cross-browser and cross-server support.
- WebSockets: a transport layer built-on TCP that uses an HTTP friendly Upgrade handshake. Unlike TCP, which is a streaming transport, WebSockets is a message based transport: messages are delimited on the wire and are re-assembled in-full before delivery to the application. WebSocket connections are bi-directional, full-duplex and long-lived. After the initial handshake request/response, there is no transactional semantics and there is very little per message overhead. The client and server may send messages at any time and must handle message receipt asynchronously.
- SPDY: a Google initiated proposal to extend HTTP using a more efficient wire protocol but maintaining all HTTP semantics (request/response, cookies, encoding). SPDY introduces a new framing format (with length-prefixed frames) and specifies a way to layering HTTP request/response pairs onto the new framing layer. Headers can be compressed and new headers can be sent after the connection has been established. There are real world implementations of SPDY in browsers and servers.
- HTTP 2.0: has similar goals to SPDY: reduce HTTP latency and overhead while preserving HTTP semantics. The current draft is derived from SPDY and defines an upgrade handshake and data framing that is very similar the the WebSocket standard for handshake and framing. An alternate HTTP 2.0 draft proposal (httpbis-speed-mobility) actually uses WebSockets for the transport layer and adds the SPDY multiplexing and HTTP mapping as an WebSocket extension (WebSocket extensions are negotiated during the handshake).
- WebRTC/CU-WebRTC: proposals to allow peer-to-peer connectivity between browsers. This may enable lower average and maximum latency communication because as the underlying transport is SDP/datagram rather than TCP. This allows out-of-order delivery of packets/messages which avoids the TCP issue of latency spikes caused by dropped packets which delay delivery of all subsequent packets (to guarantee in-order delivery).
- QUIC: is an experimental protocol aimed at reducing web latency over that of TCP. On the surface, QUIC is very similar to TCP+TLS+SPDY implemented on UDP. QUIC provides multiplexing and flow control equivalent to HTTP/2, security equivalent to TLS, and connection semantics, reliability, and congestion control equivalentto TCP. Because TCP is implemented in operating system kernels, and middlebox firmware, making significant changes to TCP is next to impossible. However, since QUIC is built on top of UDP, it suffers from no such limitations. QUIC is designed and optimised for HTTP/2 semantics.
References:
- HTTP:
- Wikipedia HTTP Page
- W3C List of HTTP related Drafts/Protocols
- List of IETF HTTP/1.1 and HTTP/2.0 Drafts
- Server-Sent Event:
- W3C Server-Sent Events/EventSource Candidate Recommendation
- W3C Server-Sent Events/EventSource Draft
- WebSockets:
- IETF RFC 6455 WebSockets Protocol
- IETF RFC 6455 WebSocket Errata
- SPDY:
- IETF SPDY Draft
- HTTP 2.0:
- IETF HTTP 2.0 httpbis-http2 Draft
- IETF HTTP 2.0 httpbis-speed-mobility Draft
- IETF httpbis-network-friendly Draft - an older HTTP 2.0 related proposal
- WebRTC:
- W3C WebRTC API Draft
- List of IETF WebRTC Drafts
- IETF WebRTC Overview Draft
- IETF WebRTC DataChannel Draft
- Microsoft CU-WebRTC Proposal Start Page
- QUIC:
- QUIC Chrominum Project
- IETF QUIC Draft
这篇关于WebSockets 协议与 HTTP的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!