WebSockets协议与HTTP

6bc51xsx  于 2022-12-23  发布在  其他
关注(0)|答案(6)|浏览(162)

关于WebSocket和HTTP有很多博客和讨论,很多开发者和站点都极力提倡WebSocket,但我还是不能理解为什么。
例如(WebSocket爱好者的参数):
HTML5 Web套接字代表了Web通信的下一个发展方向-一种全双工、双向通信通道,通过Web上的单个套接字运行。-websocket.org
HTTP支持流式传输:请求正文流(在上载大文件时使用)和响应正文流。
在与WebSocket建立连接期间,客户端和服务器每帧交换2字节的数据,而在进行连续轮询时,HTTP头为8 KB。
为什么这2个字节不包括TCP和TCP协议下的开销?

GET /about.html HTTP/1.1
Host: example.org

这是约48字节的HTTP标头。
HTTP分块编码-Chunked transfer encoding

23
This is the data in the first chunk
1A
and this is the second one
3
con
8
sequence
0
  • 因此,每个块的开销并不大。

而且,这两种协议都在TCP上工作,所以所有长时间连接的TCP问题仍然存在。

问题:

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

qhhrdooz

qhhrdooz1#

    • 1)为什么WebSockets协议更好?**

WebSockets更适合于涉及低延迟通信的情况,尤其是客户端到服务器消息的低延迟。对于服务器到客户端数据,您可以使用长时间保持的连接和分块传输获得相当低的延迟。但是,这对客户端到服务器延迟没有帮助,因为客户端到服务器延迟需要为每个客户端到服务器消息建立新的连接。
48字节的HTTP握手对于真实的HTTP浏览器连接来说是不现实的,在真实的HTTP浏览器连接中,通常会有数千字节的数据作为请求的一部分发送(双向),包括许多报头和cookie数据。

  • 示例请求(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协议,例如SPDYHTTP 2.0QUIC,以达到更好的性能和更低的延迟。这将改善正常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),它们也具有特定的事务含义。然而,如HTTP2.0草案提案的介绍中所述,HTTP 1.1流水线没有得到广泛部署,因此这极大地限制了HTTP 1.1解决浏览器和服务器之间延迟的实用性。
      • 长轮询**:对HTTP(1.0或1.1)的一种"攻击",其中服务器不立即响应(或仅使用报头部分响应)客户端请求。在服务器响应之后,客户端立即发送新请求(如果通过HTTP 1.1,则使用相同的连接)。
      • HTTP流**:允许服务器向单个客户端请求发送多个响应的各种技术(多部分/分块响应)。W3C正在使用text/event-stream MIME类型将其标准化为Server-Sent Events。浏览器API(与WebSocket API非常相似)称为EventSource API。
      • Comet/服务器推送**:这是一个总括性的术语,包括长轮询和HTTP流。2 Comet库通常支持多种技术来尝试和最大化跨浏览器和跨服务器的支持。
      • 网络套接字**:使用HTTP友好升级握手的传输层内置TCP。与TCP不同,它是一种流传输,WebSockets是基于消息的传输:消息在网络上被分隔,并在传递到应用程序之前被完整地重新组装。WebSocket连接是双向、全双工和长期的。在初始握手请求/响应之后,没有事务语义,并且每个消息的开销非常小。客户端和服务器可以在任何时候发送消息,并且必须异步处理消息接收。
      • 国家采购司**:一个Google发起的提案,使用更有效的有线协议扩展HTTP,但保留所有HTTP语义(请求/响应,cookie,SPDY引入了一种新的成帧格式(带有长度前缀的帧),并指定将HTTP请求/响应对分层到新帧层的方法。可以压缩报头,并在建立连接后发送新报头。在浏览器和服务器中有SPDY的实际实现。
      • HTTP 2.0**:与SPDY有着相似的目标,在保留HTTP语义的同时减少HTTP延迟和开销。当前草案源自SPDY,定义了一个升级握手和数据成帧,与WebSocket握手和成帧标准非常相似。另一个HTTP2.0草案提案(httpbis-speed-mobility)实际上使用WebSocket作为传输层,并添加了SPDY多路复用和HTTPMap作为WebSocket扩展(WebSocket扩展在握手期间协商)。
      • 网络实时时钟/CU-网络实时时钟**:建议允许浏览器之间的对等连接。这可以实现较低的平均延迟和最大延迟通信,因为底层传输是SDP/数据报而不是TCP。这允许数据包/消息的无序传递,从而避免TCP因丢弃数据包而延迟所有后续数据包传递的延迟峰值问题(以保证有序传递)。
      • 快速**:是一种实验性协议,旨在比TCP减少Web延迟。从表面上看,QUIC非常类似于在UDP上实现的TCP + TLS + SPDY。QUIC提供与HTTP/2等效的多路复用和流量控制,与TLS等效的安全性,以及与TCP等效的连接语义、可靠性和拥塞控制。由于TCP在操作系统内核和中间盒固件中实现,对TCP进行重大的改变几乎是不可能的。2然而,由于QUIC是建立在UDP之上的,它就没有这样的限制。3 QUIC是为HTTP 2语义而设计和优化的。
    • 参考文献**:
    • 超文本传输协议**:
  • Wikipedia HTTP Page

  • W3C List of HTTP related Drafts/Protocols

  • List of IETF HTTP/1.1 and HTTP/2.0 Drafts

    • 服务器发送的事件**:
  • W3C Server-Sent Events/EventSource Candidate Recommendation

  • W3C Server-Sent Events/EventSource Draft

    • 网络套接字**:
  • IETF RFC 6455 WebSockets Protocol

  • IETF RFC 6455 WebSocket Errata

    • 国家采购司**:
  • 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-较早的HTTP 2.0相关提案

    • 网络实时技术中心**:
  • W3C WebRTC API Draft

  • List of IETF WebRTC Drafts

  • IETF WebRTC Overview Draft

  • IETF WebRTC DataChannel Draft

  • Microsoft CU-WebRTC Proposal Start Page

    • 快速**:
  • QUIC Chrominum Project

  • IETF QUIC Draft

czfnxgou

czfnxgou2#

你似乎认为WebSocket是HTTP的替代品,但事实并非如此,它是一个扩展。
WebSockets的主要应用是运行在网页浏览器上并从服务器接收实时数据的Javascript应用,游戏就是一个很好的例子。
在WebSockets之前,JavaScript应用程序与服务器交互的唯一方法是通过XmlHttpRequest,但这些方法有一个主要缺点:服务器不能发送数据,除非客户端明确请求它。
但新的WebSocket功能允许服务器随时发送数据,这使得基于浏览器的游戏可以以更低的延迟实现,而且不必使用 AJAX 长轮询或浏览器插件等丑陋的黑客攻击。

那么,为什么不对流式请求和响应使用普通HTTP呢

在对另一个答案的评论中,您建议只异步传输客户端请求和响应正文。
实际上,WebSocket基本上就是这样,从客户端打开WebSocket连接的尝试起初看起来像是一个HTTP请求,而是在报头中的一个特殊指令(Upgrade: websocket)告诉服务器开始以这种异步模式进行通信。First drafts of the WebSocket protocol并没有比这更多的内容,只是进行了一些握手,以确保服务器实际上理解客户机希望进行异步通信。但是后来人们意识到代理服务器会对此感到困惑,因为它们习惯于HTTP的常见请求/响应模型。针对代理服务器的potential attack scenario被发现。为了防止这种情况,有必要使WebSocket流量看起来不像任何正常的HTTP流量。这就是为什么在the final version of the protocol中引入了掩码。

um6iljoc

um6iljoc3#

常规的REST API使用HTTP作为通信的底层协议,它遵循请求和响应范式,这意味着通信涉及客户端从服务器请求一些数据或资源,以及服务器对该客户端的响应。因此,每个请求-响应周期最终都必须重复报头和元数据信息。如果频繁重复请求,则会导致额外的延迟。响应周期。

使用WebSockets,虽然通信仍然作为初始HTTP握手开始,但是它被进一步升级以遵循WebSockets协议(即,如果服务器和客户端都遵从该协议,因为不是所有实体都支持WebSockets协议)。
现在有了WebSockets,就可以在客户端和服务器之间建立全双工的持久连接,这意味着与请求和响应不同,只要应用程序在运行,连接就保持打开状态(即,它是持久的),并且由于它是全双工的,双向同时通信是可能的,即现在服务器能够发起通信并在新数据(客户感兴趣的)变得可用。

WebSockets协议是有状态的,允许您实现发布-订阅(或发布/订阅)消息传递模式,这是实时技术中使用的主要概念,在这种模式下,您可以以服务器推送的形式获得新的更新,而无需客户端请求(刷新页面)。这类应用程序的例子有优步汽车的位置跟踪,推送通知,股票市场价格实时更新,聊天、多人游戏、实时在线协作工具等。
您可以查看Websockets上的一篇深入文章,其中解释了该协议的历史、它是如何产生的、它的用途以及您如何自己实现它。
下面是我做的一个关于WebSockets以及它们与使用常规REST API的区别的演示视频:Standardisation and leveraging the exponential rise in data streaming

ufj5ltwl

ufj5ltwl4#

对于TL; DR,这里有2美分和一个更简单的版本来回答你的问题:

  • WebSockets通过HTTP提供以下好处:
  • 在连接期间保持持久的有状态连接
  • 低延迟:服务器/客户端之间的近实时通信,因为没有HTTP要求的为每个请求重新建立连接的开销。
  • 全双工:服务器和客户端可以同时发送/接收
  • WebSocket和HTTP协议是为解决不同的问题而设计的,例如WebSocket是为改善双向通信而设计的,而HTTP是无状态的,使用请求/响应模型进行分发。除了由于传统原因(防火墙/代理渗透)而共享端口之外,将它们合并为一个协议没有太多的共同点。
qojgxg4l

qojgxg4l5#

为什么WebSockets协议更好?

我不认为我们可以把他们放在一起比较,就像谁更好一样。这不是一个公平的比较,仅仅因为他们解决的是两个不同的问题。他们的要求不同。这就像比较苹果和桔子一样。他们是不同的。
HTTP是一种请求-响应协议。客户端(浏览器)需要什么,服务器就给它。也就是说,如果客户端需要的数据量很大,服务器可能会发送流数据以避免不必要的缓冲问题。这里的主要需求或问题是如何从客户端发出请求,以及如何响应他们请求的资源(超文本)。这就是HTTP的亮点。
在HTTP协议中,只有客户端请求.服务器只响应.

WebSocket不是只有客户端才能请求的请求-响应协议。它是套接字(非常类似于TCP socket)。意思是一旦连接打开,任何一方都可以发送数据,直到下面的TCP连接关闭。它就像一个普通的socket。与TCP socket唯一的区别是WebSocket可以在web上使用。在web上,我们对普通套接字有很多限制。2大多数防火墙会阻止HTTP使用的端口80和433以外的端口。3代理和中介也会有问题。4所以为了使协议更容易部署到现有的基础设施WebSocket使用HTTP握手来升级。这意味着当第一次连接要打开时,客户端发送一个HTTP请求告诉服务器说“这不是HTTP请求,请升级到WebSocket协议”。

Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13

一旦服务器理解请求并升级到WebSocket协议,就不再应用任何HTTP协议。
所以我的答案是没有一个比另一个更好。他们完全不同。

为什么要实现它而不是更新HTTP协议?

好吧,我们也可以把所有东西都命名为HTTP。但是我们可以吗?如果它们是两个不同的东西,我会喜欢两个不同的名字。Hickson和Michael Carter也是。

watbbzwu

watbbzwu6#

其他的答案似乎没有触及这里的一个关键方面,那就是你没有提到需要支持Web浏览器作为客户端。上面普通HTTP的大多数限制都是假设你将使用浏览器/ JS实现。
HTTP协议完全能够进行全双工通信;法律的的做法是让客户端使用分块编码传输来执行POST,让服务器使用分块编码主体来返回响应。2这会将头开销减少到初始化时间。
因此,如果您所寻找的只是全双工、同时控制客户端和服务器,并且对WebSockets的额外帧/特性不感兴趣,那么我认为HTTP是一种更简单的方法,具有更低的延迟/CPU(尽管两者的延迟实际上只有微秒或更少的差异)。

相关问题