适配器
适配器是一个服务器端组件,负责向所有或部分客户端广播事件。
¥An Adapter is a server-side component which is responsible for broadcasting events to all or a subset of clients.
当扩展到多个 Socket.IO 服务器时,你将需要用另一种实现替换默认的内存适配器,以便事件正确路由到所有客户端。
¥When scaling to multiple Socket.IO servers, you will need to replace the default in-memory adapter by another implementation, so the events are properly routed to all clients.
以下是我们团队维护的适配器列表:
¥Here is the list of adapters that are maintained by our team:
¥the Redis adapter
¥the MongoDB adapter
¥the Postgres adapter
集群适配器 号
¥the Cluster adapter
¥the AWS SQS adapter
还有其他几个由(太棒了!)社区维护的选项:
¥There are also several other options which are maintained by the (awesome!) community:
请注意,当使用多个 Socket.IO 服务器和 HTTP 长轮询时,仍然需要启用粘性会话。更多信息在 此处。
¥Please note that enabling sticky sessions is still needed when using multiple Socket.IO servers and HTTP long-polling. More information here.
API
你可以通过以下方式访问适配器实例:
¥You can have access to the adapter instance with:
// main namespace
const mainAdapter = io.of("/").adapter; // WARNING! io.adapter() will not work
// custom namespace
const adminAdapter = io.of("/admin").adapter;
从 socket.io@3.1.0
开始,每个 Adapter 实例都会触发以下事件:
¥Starting with socket.io@3.1.0
, each Adapter instance emits the following events:
create-room
(参数:房间)¥
create-room
(argument: room)delete-room
(参数:房间)¥
delete-room
(argument: room)join-room
(参数:房间、id)¥
join-room
(argument: room, id)leave-room
(参数:房间、id)¥
leave-room
(argument: room, id)
示例:
¥Example:
io.of("/").adapter.on("create-room", (room) => {
console.log(`room ${room} was created`);
});
io.of("/").adapter.on("join-room", (room, id) => {
console.log(`socket ${id} has joined room ${room}`);
});
触发器
¥Emitter
大多数适配器实现都附带其关联的触发器包,该包允许从另一个 Node.js 进程与 Socket.IO 服务器组进行通信。
¥Most adapter implementations come with their associated emitter package, which allows communicating to the group of Socket.IO servers from another Node.js process.
例如,这在微服务设置中可能很有用,其中所有客户端都连接到微服务 M1,而微服务 M2 使用触发器广播数据包(单向通信)。
¥This may be useful for example in a microservice setup, where all clients connect to the microservice M1, while the microservice M2 uses the emitter to broadcast packets (uni-directional communication).
触发器备忘单
¥Emitter cheatsheet
// to all clients
emitter.emit(/* ... */);
// to all clients in "room1"
emitter.to("room1").emit(/* ... */);
// to all clients in "room1" except those in "room2"
emitter.to("room1").except("room2").emit(/* ... */);
const adminEmitter = emitter.of("/admin");
// to all clients in the "admin" namespace
adminEmitter.emit(/* ... */);
// to all clients in the "admin" namespace and in the "room1" room
adminEmitter.to("room1").emit(/* ... */);
触发器还支持 socket.io@4.0.0
中添加的实用方法:
¥The emitter also supports the utility methods that were added in socket.io@4.0.0
:
socketsJoin()
// make all Socket instances join the "room1" room
emitter.socketsJoin("room1");
// make all Socket instances of the "admin" namespace in the "room1" room join the "room2" room
emitter.of("/admin").in("room1").socketsJoin("room2");
socketsLeave()
// make all Socket instances leave the "room1" room
emitter.socketsLeave("room1");
// make all Socket instances in the "room1" room leave the "room2" and "room3" rooms
emitter.in("room1").socketsLeave(["room2", "room3"]);
// make all Socket instances in the "room1" room of the "admin" namespace leave the "room2" room
emitter.of("/admin").in("room1").socketsLeave("room2");
disconnectSockets()
// make all Socket instances disconnect
emitter.disconnectSockets();
// make all Socket instances in the "room1" room disconnect (and discard the low-level connection)
emitter.in("room1").disconnectSockets(true);
// make all Socket instances in the "room1" room of the "admin" namespace disconnect
emitter.of("/admin").in("room1").disconnectSockets();
// this also works with a single socket ID
emitter.of("/admin").in(theSocketId).disconnectSockets();
serverSideEmit()
// emit an event to all the Socket.IO servers of the cluster
emitter.serverSideEmit("hello", "world");
// Socket.IO server (server-side)
io.on("hello", (arg) => {
console.log(arg); // prints "world"
});