发送事件
有几种方法可以在服务器和客户端之间发送事件。
提示
对于 TypeScript 用户,可以为事件提供类型提示。请查看 此处.
基本 emit
Socket.IO API 借鉴了 Node.js EventEmitter,这意味着您可以在一端发出事件,并在另一端注册监听器
服务器
io.on("connection", (socket) => {
socket.emit("hello", "world");
});
客户端
socket.on("hello", (arg) => {
console.log(arg); // world
});
这在另一个方向也适用
服务器
io.on("connection", (socket) => {
socket.on("hello", (arg) => {
console.log(arg); // world
});
});
客户端
socket.emit("hello", "world");
您可以发送任意数量的参数,并且所有可序列化数据结构都受支持,包括二进制对象,如 Buffer 或 TypedArray。
服务器
io.on("connection", (socket) => {
socket.emit("hello", 1, "2", { 3: '4', 5: Buffer.from([6]) });
});
客户端
// client-side
socket.on("hello", (arg1, arg2, arg3) => {
console.log(arg1); // 1
console.log(arg2); // "2"
console.log(arg3); // { 3: '4', 5: ArrayBuffer (1) [ 6 ] }
});
无需对对象运行 JSON.stringify()
,因为它会为您完成。
// BAD
socket.emit("hello", JSON.stringify({ name: "John" }));
// GOOD
socket.emit("hello", { name: "John" });
注意
const serializedMap = [...myMap.entries()];
const serializedSet = [...mySet.keys()];
- 您可以使用
toJSON()
方法自定义对象的序列化
类示例
class Hero {
#hp;
constructor() {
this.#hp = 42;
}
toJSON() {
return { hp: this.#hp };
}
}
socket.emit("here's a hero", new Hero());
确认
事件很棒,但在某些情况下,您可能需要更经典的请求-响应 API。在 Socket.IO 中,此功能称为确认。
您可以将回调作为 emit()
的最后一个参数添加,并且当另一方确认事件时,将调用此回调
服务器
io.on("connection", (socket) => {
socket.on("update item", (arg1, arg2, callback) => {
console.log(arg1); // 1
console.log(arg2); // { name: "updated" }
callback({
status: "ok"
});
});
});
客户端
socket.emit("update item", "1", { name: "updated" }, (response) => {
console.log(response.status); // ok
});
带超时
从 Socket.IO v4.4.0 开始,您现在可以为每个 emit 分配超时
socket.timeout(5000).emit("my-event", (err) => {
if (err) {
// the other side did not acknowledge the event in the given delay
}
});
您也可以同时使用超时和 确认
socket.timeout(5000).emit("my-event", (err, response) => {
if (err) {
// the other side did not acknowledge the event in the given delay
} else {
console.log(response);
}
});
易失性事件
易失性事件是指在底层连接未准备好时不会发送的事件(在可靠性方面有点像 UDP)。
例如,如果您需要发送在线游戏中角色的位置(因为只有最新的值有用),这会很有趣。
socket.volatile.emit("hello", "might or might not be received");
另一个用例是在客户端未连接时丢弃事件(默认情况下,事件会缓冲直到重新连接)。
示例
服务器
io.on("connection", (socket) => {
console.log("connect");
socket.on("ping", (count) => {
console.log(count);
});
});
客户端
let count = 0;
setInterval(() => {
socket.volatile.emit("ping", ++count);
}, 1000);
如果您重新启动服务器,您将在控制台中看到
connect
1
2
3
4
# the server is restarted, the client automatically reconnects
connect
9
10
11
如果没有 volatile
标志,您将看到
connect
1
2
3
4
# the server is restarted, the client automatically reconnects and sends its buffered events
connect
5
6
7
8
9
10
11