简而言之,socket.io 的工作原理如下:
首先,socket.io 是 webSocket 之上的一个薄协议层,所以说真的,我们将讨论 webSocket 的工作原理。
一个 webSocket 连接从一个普通的 HTTP 请求开始,该请求带有一个特殊的标头集,即 Upgrade 标头,它请求从 HTTP 协议升级到 webSocket 协议。
当服务器收到请求并看到升级标头时,如果它支持该协议,则它会以 101 响应(切换协议)和其他一些标头进行响应。当客户端收到此响应(以及其他一些与安全性相关的标头)时,两端都会将该套接字上的协议切换到 webSocket 协议。
因为 webSocket 协议设计为持续连接客户端和服务器,所以保持原始套接字打开以供将来通信,事实上,它一直保持打开状态,直到任何一方决定它们最终完成了 webSocket 通信通道然后关闭套接字。
因此,套接字会长时间保持打开状态。这使得任何一方都可以随时向另一方发送消息。这就是它避免轮询的方式。而不是来自客户端的临时 HTTP 请求询问服务器:“你有 m 的任何新数据吗?”,客户端可以坐在那里监听传入的消息。当服务器有新的东西要发送给客户端时,它已经有这个打开的 webSocket 连接,它可以随时向客户端发送一条消息。
Socket.io 在 webSocket 之上添加了一些功能。它添加的主要内容是:1)如果套接字连接由于任何原因丢失,则自动重新连接,2)从一端到另一端的定期 ping 以检测连接何时丢失,以及 3)一个消息传递层,使得它变得微不足道从一端发送命名消息到另一端。
我想知道 socket.io 方法是如何工作的
事件,我读过它不像长轮询方法,而是
一种可以在所有不同浏览器上运行的不同浏览器
它不是长轮询,因为它在客户端期间保持套接字连接打开。这种长期开放的连接可用于将消息从客户端发送到服务器或从服务器发送到客户端,而无需在每次要发送时都创建新连接。这适用于任何支持 webSocket 协议的浏览器。
客户端如何在没有长时间的情况下与服务器保持联系
轮询请求?
webSocket 连接被设计为长寿命连接,而不是典型的临时 HTTP 连接。
如果你想了解更多关于 webSocket 协议本身的信息,你可以在这篇 MDN 文章中看到一个很好的描述:Writing webSocket Servers。
以下是打开 webSocket 的初始客户端请求示例:
GET /chat HTTP/1.1
Host: example.com:8000
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Version: 13
而且,这是一个典型的服务器响应,它确认切换到 webSocket 协议:
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
然后,一旦协议被更改,webSocket 数据帧如下所示:
0 1 2 3
0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7
+-+-+-+-+-------+-+-------------+-------------------------------+
|F|R|R|R| opcode|M| Payload len | Extended payload length |
|I|S|S|S| (4) |A| (7) | (16/64) |
|N|V|V|V| |S| | (if payload len==126/127) |
| |1|2|3| |K| | |
+-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - +
4 5 6 7
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
| Extended payload length continued, if payload len == 127 |
+ - - - - - - - - - - - - - - - +-------------------------------+
8 9 10 11
+ - - - - - - - - - - - - - - - +-------------------------------+
| |Masking-key, if MASK set to 1 |
+-------------------------------+-------------------------------+
12 13 14 15
+-------------------------------+-------------------------------+
| Masking-key (continued) | Payload Data |
+-------------------------------- - - - - - - - - - - - - - - - +
: Payload Data continued ... :
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
| Payload Data continued ... |
+---------------------------------------------------------------+
Socket.io 使用 webSocket 数据帧,但在该帧的有效负载中插入了自己的消息格式,允许它发送命名消息。