Websockets是如何实现的?

23
  • Websockets是如何实现的?
  • 与长轮询相比,这项新技术背后的算法是什么?
  • 它们在性能方面如何比长轮询更好?

我提出这些问题是因为这里有Jetty websocket实现(服务器端)的示例代码。

 

如果我们等待足够长的时间,超时将发生,导致客户端显示以下消息。

这绝对是我在使用长轮询时遇到的问题。 它会停止进程以防止服务器超载,不是吗?


请解释一下你的问题究竟与主题有何关联?你并没有提出任何实际的问题 - 如果你知道WebSockets是如何实现的,那么这对你来说解决了什么问题呢?而且,询问“在性能方面更好”的问题也使得问题变得过于宽泛。 - JK.
请注意,我刚刚更新了我的问题。 - David
2个回答

44
“Websockets是如何实现的?”
webSockets的实现方式如下:
1.客户端通过带有“upgrade”标头的HTTP请求向服务器发出请求。 2.如果服务器同意升级,则客户端和服务器交换一些安全凭据,并将现有TCP套接字上的协议从HTTP切换到webSocket。 3.现在,有一个持久的打开的TCP套接字连接客户端和服务器。 4.任何一方都可以随时在此打开的套接字上发送数据。 5.所有数据必须以非常特定的webSocket数据包格式发送。
由于双方都同意保持套接字打开,因此这为服务器提供了一个渠道,可以在有新内容需要发送时向客户端“推送”信息。这通常比使用客户端驱动的Ajax调用更有效,其中客户端必须定期轮询新信息。而且,如果客户端需要向服务器发送大量消息(例如类似多人游戏的情况),则使用已经打开的套接字向服务器发送快速消息也比Ajax调用更有效。
因为webSockets的初始化方式(从HTTP请求开始,然后重新利用该套接字),它们与现有的Web基础架构完全兼容,甚至可以在与现有Web请求相同的端口上运行(例如端口80或443)。这使得跨源安全更加简单,并且使客户端或服务器端基础架构中的任何人都不必修改任何基础架构来支持webSocket连接。
“这种新技术背后的算法是什么(与长轮询相比)?”
这篇文章Writing WebSocket Servers很好地总结了webSocket连接算法和webSocket数据格式的工作原理。
“它们如何在性能方面优于长轮询?”
由其本质,长轮询有点像一个hack。之所以发明它,是因为没有更好的选择来向客户端发送服务器启动的数据。以下是步骤:
  1. 客户端发起一个http请求,请求获取来自服务器的新数据。
  2. 如果服务器有新的数据,它会立即返回这些数据并且客户端会再次发起一个http请求请求更多数据。如果服务器没有新的数据,则它会暂时保持连接而不提供响应,使得请求处于挂起状态(套接字处于打开状态,客户端正在等待响应)。
  3. 如果在请求仍然处于挂起状态时,服务器获得了一些数据,则将这些数据组织成一个响应并返回该挂起请求的响应。
  4. 如果一段时间内没有收到任何数据,则最终请求将超时。此时,客户端将意识到没有返回新数据,并将开始一个新的请求。
  5. 反复执行以上步骤。每次返回数据或者每次挂起请求超时都会随之跟着一个来自客户端的ajax请求。

因此,尽管webSocket使用一个长连接套接字,可以让客户端或服务器相互发送数据,但长轮询则是由客户端一遍又一遍地向服务器询问“你还有更多的数据吗?”每次询问都需要发起新的http请求。

当长轮询正确使用时,它在服务器基础设施、带宽使用、移动电池寿命等方面效率不高。

我想要解释一下:Websockets保持C/S之间的开放连接与Long Polling等待过程不太相同吗?换句话说,为什么Websockets不会使服务器超载?

在客户端和服务器之间维护一个开放的webSocket连接对于服务器来说是非常廉价的事情(只是一个TCP套接字)。一个非活动但开放的TCP套接字不需要服务器CPU,并且只需要极少量的内存来跟踪套接字。适当配置的服务器可以同时拥有数十万个开放的套接字。

另一方面,即使没有新信息要发送给客户端,执行长轮询的客户端也必须定期重新建立其连接。每次重新建立新连接时,都会进行TCP套接字拆除和新连接,然后处理传入的HTTP请求。

以下是有关扩展主题的一些有用参考资料:


1
谢谢。你回答的最后一部分是我想要的。但是,你能详细说明并提供外部来源吗? - David
1
@David - 我在我的回答中添加了一些参考资料。 - jfriend00
所以,如果我理解你的回答,那么对于客户端的性能没有影响,例如移动电池? - Emrys Myrooin

6

关于web sockets、长轮询和其他方法的非常好的解释:

在什么情况下,AJAX长/短轮询比HTML5 WebSockets更可取?

长轮询 - 请求→等待→响应。与AJAX一样创建到服务器的连接,但会保持活动状态一段时间(不长),在连接打开期间,客户端可以从服务器接收数据。当连接由于超时或数据eof而关闭后,客户端必须定期重新连接。在服务器端,它仍然像AJAX一样被视为HTTP请求,除了现在或将来由应用程序逻辑定义的请求回复。支持所有主要浏览器。

WebSockets - 客户端↔服务器。创建到服务器的TCP连接,并保持所需的时间。服务器或客户端可以轻松地关闭它。如果客户端经过HTTP兼容握手过程,则可以交换来自服务器和客户端的任何时间的数据。如果应用程序需要频繁的双向数据交换,则非常高效。WebSockets具有数据帧,其中包括每个从客户端发送到服务器的消息掩码,因此数据被简单加密。支持表格(非常好)。

总的来说,套接字比长轮询具有更好的性能,因此应该使用它们而不是长轮询。


是的,我之前已经看过这篇帖子。但它并没有真正回答我的问题。我想要的是关于这个问题的解释:Websockets保持C/S之间的开放连接事实不完全等同于长轮询中的“等待”过程吗?换句话说,为什么Websockets不会使服务器负载过重? - David
@David - WebSocket 服务器的设计考虑到大量持久连接,而(传统的)HTTP 服务器则专注于快速处理请求。 - gzost

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接