简介
如果您是 Socket.IO 的新手,我们建议您查看我们的 教程.
什么是 Socket.IO
Socket.IO 是一个库,它使客户端和服务器之间能够进行低延迟、双向和基于事件的通信。


Socket.IO 连接可以使用不同的底层传输建立
- HTTP 长轮询
- WebSocket
- WebTransport
Socket.IO 会根据以下情况自动选择最佳可用选项
您可以在 "工作原理" 部分 中找到更多关于此方面的详细信息。
服务器实现
语言 | 网站 |
---|---|
JavaScript (Node.js) | - 安装步骤 - API - 源代码 |
JavaScript (Deno) | https://github.com/socketio/socket.io-deno |
Java | https://github.com/mrniko/netty-socketio |
Java | https://github.com/trinopoty/socket.io-server-java |
Python | https://github.com/miguelgrinberg/python-socketio |
Golang | https://github.com/googollee/go-socket.io |
Rust | https://github.com/Totodore/socketioxide |
客户端实现
Socket.IO 不是什么
Socket.IO 不是 WebSocket 实现。
虽然 Socket.IO 确实在可能的情况下使用 WebSocket 进行传输,但它会为每个数据包添加额外的元数据。这就是为什么 WebSocket 客户端无法成功连接到 Socket.IO 服务器,而 Socket.IO 客户端也无法连接到纯 WebSocket 服务器的原因。
// WARNING: the client will NOT be able to connect!
const socket = io("ws://echo.websocket.org");
如果您正在寻找纯 WebSocket 服务器,请查看 ws 或 µWebSockets.js。
还有一些 讨论 涉及在 Node.js 核心代码中包含 WebSocket 服务器。
在客户端方面,您可能对 robust-websocket 包感兴趣。
Socket.IO 不适合在移动应用程序的后台服务中使用。
Socket.IO 库会与服务器保持开放的 TCP 连接,这可能会导致您的用户电池电量消耗过快。对于这种情况,请使用专门的消息传递平台,例如 FCM。
功能
以下是 Socket.IO 在纯 WebSockets 之上提供的功能
HTTP 长轮询回退
如果无法建立 WebSocket 连接,连接将回退到 HTTP 长轮询。
十多年前该项目创建时,这是人们使用 Socket.IO 的首要原因(!),因为浏览器对 WebSockets 的支持还处于起步阶段。
即使现在大多数浏览器都支持 WebSockets(超过 97%),它仍然是一个很棒的功能,因为我们仍然收到用户报告,他们无法建立 WebSocket 连接,因为他们位于某些配置错误的代理后面。
自动重新连接
在某些特定情况下,服务器和客户端之间的 WebSocket 连接可能会中断,而双方都无法意识到链接已断开。
这就是为什么 Socket.IO 包含心跳机制,它会定期检查连接状态。
当客户端最终断开连接时,它会自动以指数级回退延迟重新连接,以避免对服务器造成过载。
数据包缓冲
当客户端断开连接时,数据包会自动缓冲,并在重新连接后发送。
更多信息 这里。
确认
Socket.IO 提供了一种方便的方式来发送事件并接收响应
发送方
socket.emit("hello", "world", (response) => {
console.log(response); // "got it"
});
接收方
socket.on("hello", (arg, callback) => {
console.log(arg); // "world"
callback("got it");
});
您还可以添加超时
socket.timeout(5000).emit("hello", "world", (err, response) => {
if (err) {
// the other side did not acknowledge the event in the given delay
} else {
console.log(response); // "got it"
}
});
广播
在服务器端,您可以将事件发送到 所有已连接的客户端 或 客户端子集
// to all connected clients
io.emit("hello");
// to all connected clients in the "news" room
io.to("news").emit("hello");
这在 扩展到多个节点 时也有效。
多路复用
命名空间允许您将应用程序的逻辑拆分到单个共享连接上。例如,如果您想创建一个只有授权用户才能加入的“管理员”通道,这将非常有用。
io.on("connection", (socket) => {
// classic users
});
io.of("/admin").on("connection", (socket) => {
// admin users
});
更多信息 这里。
常见问题
今天还需要 Socket.IO 吗?
这是一个合理的问题,因为 WebSockets 现在 几乎在所有地方 都受支持。
话虽如此,我们认为,如果您在应用程序中使用纯 WebSockets,您最终将需要实现 Socket.IO 中已包含(并经过实战检验)的大多数功能,例如 重新连接、确认 或 广播。
Socket.IO 协议的开销是多少?
socket.emit("hello", "world")
将作为包含 42["hello","world"]
的单个 WebSocket 帧发送,其中
4
是 Engine.IO 的“消息”数据包类型2
是 Socket.IO 的“消息”数据包类型["hello","world"]
是JSON.stringify()
-ed 版本的参数数组
因此,每条消息都会增加一些额外的字节,这可以通过使用 自定义解析器 进一步减少。
浏览器捆绑包本身的大小为 10.4 kB
(已缩小并 gzip 压缩)。
您可以在 这里 找到 Socket.IO 协议的详细信息。
某些功能无法正常工作,请帮忙?
请查看我们的 故障排除指南。