有很多关于WebSocket和HTTP的博客和讨论,很多开发者和网站都强烈提倡WebSocket,但我仍然不明白为什么。

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

HTML5 Web Sockets代表了Web通信的下一次发展——通过Web上的单个套接字操作的全双工双向通信通道。——websocket.org

HTTP支持流:请求正文流(你在上传大文件时使用它)和响应正文流。

在与WebSocket连接期间,客户端和服务器每帧交换数据,每帧交换数据2字节,而当您进行连续轮询时,HTTP报头的交换数据为8千字节。

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

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

这是约48字节的HTTP报头。

HTTP分块编码-分块传输编码:

23
This is the data in the first chunk
1A
and this is the second one
3
con
8
sequence
0

因此,每个块的开销并不大。

此外,这两种协议都在TCP上工作,因此所有与长时间连接有关的TCP问题仍然存在。

问题:

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


当前回答

为什么WebSockets协议更好?

我不认为我们可以把他们放在一起比较,比如谁更好。仅仅因为他们在解决两个不同的问题,这样的比较是不公平的。他们的要求是不同的。这就像比较苹果和橘子一样。他们是不同的。

HTTP是一种请求-响应协议。客户端(浏览器)想要什么,服务器就给它。这是。如果客户端想要的数据很大,服务器可能会发送流数据以避免不必要的缓冲区问题。这里的主要需求或问题是如何从客户端发出请求,以及如何响应他们请求的资源(超文本)。这就是HTTP的亮点所在。

在HTTP中,只有客户端请求。服务器只响应。

WebSocket is not a request-response protocol where only the client can request. It is a socket(very similar to TCP socket). Mean once the connection is open, either side can send data until the underlining TCP connection is closed. It is just like a normal socket. The only difference with TCP socket is WebSocket can be used on the web. On the web, we have many restrictions on a normal socket. Most firewalls will block other ports than 80 and 433 that HTTP used. Proxies and intermediaries will be problematic as well. So to make the protocol easier to deploy to existing infrastructures WebSocket use HTTP handshake to upgrade. That means when the first time connection is going to open, the client sent an HTTP request to tell the server saying "That is not HTTP request, please upgrade to WebSocket protocol".

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

一旦服务器理解了请求并升级到WebSocket协议,就不再应用HTTP协议了。

所以我的回答是,谁也不比谁强。它们完全不同。

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

我们也可以把所有东西都命名为HTTP。但是我们可以吗?如果它们是两种不同的东西,我会喜欢两个不同的名字。希克森和迈克尔·卡特也是。

其他回答

为什么WebSockets协议更好?

我不认为我们可以把他们放在一起比较,比如谁更好。仅仅因为他们在解决两个不同的问题,这样的比较是不公平的。他们的要求是不同的。这就像比较苹果和橘子一样。他们是不同的。

HTTP是一种请求-响应协议。客户端(浏览器)想要什么,服务器就给它。这是。如果客户端想要的数据很大,服务器可能会发送流数据以避免不必要的缓冲区问题。这里的主要需求或问题是如何从客户端发出请求,以及如何响应他们请求的资源(超文本)。这就是HTTP的亮点所在。

在HTTP中,只有客户端请求。服务器只响应。

WebSocket is not a request-response protocol where only the client can request. It is a socket(very similar to TCP socket). Mean once the connection is open, either side can send data until the underlining TCP connection is closed. It is just like a normal socket. The only difference with TCP socket is WebSocket can be used on the web. On the web, we have many restrictions on a normal socket. Most firewalls will block other ports than 80 and 433 that HTTP used. Proxies and intermediaries will be problematic as well. So to make the protocol easier to deploy to existing infrastructures WebSocket use HTTP handshake to upgrade. That means when the first time connection is going to open, the client sent an HTTP request to tell the server saying "That is not HTTP request, please upgrade to WebSocket protocol".

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

一旦服务器理解了请求并升级到WebSocket协议,就不再应用HTTP协议了。

所以我的回答是,谁也不比谁强。它们完全不同。

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

我们也可以把所有东西都命名为HTTP。但是我们可以吗?如果它们是两种不同的东西,我会喜欢两个不同的名字。希克森和迈克尔·卡特也是。

其他答案似乎没有触及这里的一个关键方面,那就是您没有提到需要支持web浏览器作为客户端。以上纯HTTP的大多数限制都是假设您将使用浏览器/ JS实现。

HTTP协议完全能够实现全双工通信;客户端执行带有分块编码传输的POST,服务器返回带有分块编码主体的响应,这是合法的。这将在初始化时删除头开销。

因此,如果你所追求的是全双工,同时控制客户端和服务器,并且对WebSockets的额外帧/特性不感兴趣,那么我认为HTTP是一种更简单的方法,具有更低的延迟/CPU(尽管延迟实际上只会以微秒或更短的时间为单位)。

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

使用WebSockets,尽管通信仍然以初始的HTTP握手开始,但它会进一步升级以遵循WebSockets协议(即,如果服务器和客户端都符合该协议,因为不是所有实体都支持WebSockets协议)。

现在有了WebSockets,就有可能在客户端和服务器之间建立一个全双工的持久连接。这意味着与请求和响应不同,只要应用程序在运行(即它是持久的),连接就会保持打开,并且由于它是全双工的,双向同步通信是可能的,即现在服务器能够发起通信,并在新数据(客户端感兴趣的)可用时“推送”一些数据给客户端。

The WebSockets protocol is stateful and allows you to implement the Publish-Subscribe (or Pub/Sub) messaging pattern which is the primary concept used in the real-time technologies where you are able to get new updates in the form of server push without the client having to request (refresh the page) repeatedly. Examples of such applications are Uber car's location tracking, Push Notifications, Stock market prices updating in real-time, chat, multiplayer games, live online collaboration tools, etc.

你可以在Websockets上查看一篇深入的文章,它解释了这个协议的历史,它是如何形成的,它的用途是什么,以及你如何自己实现它。

这是我做的一个关于WebSockets的演示视频,以及它们与使用常规REST api的不同之处:标准化和利用数据流的指数级增长

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

WebSockets provides these benefits over HTTP: Persistent stateful connection for the duration of the connection Low latency: near-real-time communication between server/client due to no overhead of reestablishing connections for each request as HTTP requires. Full duplex: both server and client can send/receive simultaneously WebSocket and HTTP protocol have been designed to solve different problems, I.E. WebSocket was designed to improve bi-directional communication whereas HTTP was designed to be stateless, distributed using a request/response model. Other than sharing the ports for legacy reasons (firewall/proxy penetration), there isn't much common ground to combine them into one protocol.

你似乎认为WebSocket是HTTP的替代品。事实并非如此。这是一种延伸。

WebSockets的主要用例是运行在web浏览器中的Javascript应用程序,并从服务器接收实时数据。游戏就是一个很好的例子。

在WebSockets出现之前,JavaScript应用程序与服务器交互的唯一方法是通过XmlHttpRequest。但这些都有一个主要的缺点:除非客户机显式地请求数据,否则服务器无法发送数据。

但是新的WebSocket特性允许服务器随时发送数据。这使得基于浏览器的游戏能够以更低的延迟实现,并且无需使用AJAX长轮询或浏览器插件等丑陋的技巧。

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

在对另一个答案的注释中,您建议只异步传输客户端请求和响应体。

In fact, WebSockets are basically that. An attempt to open a WebSocket connection from the client looks like a HTTP request at first, but a special directive in the header (Upgrade: websocket) tells the server to start communicating in this asynchronous mode. First drafts of the WebSocket protocol weren't much more than that and some handshaking to ensure that the server actually understands that the client wants to communicate asynchronously. But then it was realized that proxy servers would be confused by that, because they are used to the usual request/response model of HTTP. A potential attack scenario against proxy servers was discovered. To prevent this it was necessary to make WebSocket traffic look unlike any normal HTTP traffic. That's why the masking keys were introduced in the final version of the protocol.