Redis 适配器
工作原理
Redis 适配器依赖于 Redis 的 发布/订阅机制.
发送到多个客户端的每个数据包(例如 io.to("room1").emit()
或 socket.broadcast.emit()
)都会
- 发送到连接到当前服务器的所有匹配客户端
- 发布到 Redis 通道,并由集群中的其他 Socket.IO 服务器接收


此适配器的源代码可以在 此处 找到。
支持的功能
功能 | socket.io 版本 | 支持 |
---|---|---|
套接字管理 | 4.0.0 | ✅ 是(从版本 6.1.0 开始) |
服务器间通信 | 4.1.0 | ✅ 是(从版本 7.0.0 开始) |
带有确认的广播 | 4.5.0 | ✅ 是(从版本 7.2.0 开始) |
连接状态恢复 | 4.6.0 | ❌ 否 |
安装
npm install @socket.io/redis-adapter
兼容性表
Redis 适配器版本 | Socket.IO 服务器版本 |
---|---|
4.x | 1.x |
5.x | 2.x |
6.0.x | 3.x |
6.1.x | 4.x |
7.x 及更高版本 | 4.3.1 及更高版本 |
用法
使用 redis
包
redis
包似乎在重新连接后恢复 Redis 订阅方面存在问题
您可能希望改用 ioredis
包。
import { createClient } from "redis";
import { Server } from "socket.io";
import { createAdapter } from "@socket.io/redis-adapter";
const pubClient = createClient({ url: "redis://localhost:6379" });
const subClient = pubClient.duplicate();
await Promise.all([
pubClient.connect(),
subClient.connect()
]);
const io = new Server({
adapter: createAdapter(pubClient, subClient)
});
io.listen(3000);
使用 redis
包和 Redis 集群
import { createCluster } from "redis";
import { Server } from "socket.io";
import { createAdapter } from "@socket.io/redis-adapter";
const pubClient = createCluster({
rootNodes: [
{
url: "redis://localhost:7000",
},
{
url: "redis://localhost:7001",
},
{
url: "redis://localhost:7002",
},
],
});
const subClient = pubClient.duplicate();
await Promise.all([
pubClient.connect(),
subClient.connect()
]);
const io = new Server({
adapter: createAdapter(pubClient, subClient)
});
io.listen(3000);
使用 ioredis
包
import { Redis } from "ioredis";
import { Server } from "socket.io";
import { createAdapter } from "@socket.io/redis-adapter";
const pubClient = new Redis();
const subClient = pubClient.duplicate();
const io = new Server({
adapter: createAdapter(pubClient, subClient)
});
io.listen(3000);
使用 ioredis
包和 Redis 集群
import { Cluster } from "ioredis";
import { Server } from "socket.io";
import { createAdapter } from "@socket.io/redis-adapter";
const pubClient = new Cluster([
{
host: "localhost",
port: 7000,
},
{
host: "localhost",
port: 7001,
},
{
host: "localhost",
port: 7002,
},
]);
const subClient = pubClient.duplicate();
const io = new Server({
adapter: createAdapter(pubClient, subClient)
});
io.listen(3000);
使用 Redis 分片发布/订阅
分片发布/订阅是在 Redis 7.0 中引入的,旨在帮助扩展集群模式下发布/订阅的使用。
参考: https://redis.ac.cn/docs/interact/pubsub/#sharded-pubsub
可以使用 createShardedAdapter()
方法创建专用适配器
import { Server } from "socket.io";
import { createClient } from "redis";
import { createShardedAdapter } from "@socket.io/redis-adapter";
const pubClient = createClient({ host: "localhost", port: 6379 });
const subClient = pubClient.duplicate();
await Promise.all([
pubClient.connect(),
subClient.connect()
]);
const io = new Server({
adapter: createShardedAdapter(pubClient, subClient)
});
io.listen(3000);
最低要求
- Redis 7.0
redis@4.6.0
目前无法将分片适配器与 ioredis
包和 Redis 集群一起使用 (参考)。
选项
默认适配器
名称 | 描述 | 默认值 |
---|---|---|
key | Redis 发布/订阅通道的前缀。 | socket.io |
requestsTimeout | 超过此超时时间后,适配器将停止等待请求的响应。 | 5_000 |
publishOnSpecificResponseChannel | 是否将响应发布到请求节点的特定通道。 | false |
parser | 用于对发送到 Redis 的消息进行编码和解码的解析器。 | - |
将 publishOnSpecificResponseChannel
选项设置为 true
效率更高,因为响应(例如在调用 fetchSockets()
或 serverSideEmit()
时)仅发送到请求服务器,而不是发送到所有服务器。
但是,它目前默认为 false
,以实现向后兼容。
分片适配器
名称 | 描述 | 默认值 |
---|---|---|
channelPrefix | Redis 发布/订阅通道的前缀。 | socket.io |
subscriptionMode | 订阅模式会影响适配器使用的 Redis 发布/订阅通道数量。 | dynamic |
常见问题
Redis 中是否存储了任何数据?
没有,Redis 适配器使用 发布/订阅机制 在 Socket.IO 服务器之间转发数据包,因此 Redis 中没有存储任何键。
在使用 Redis 适配器时,我是否仍然需要启用粘性会话?
是的。如果未这样做,将导致 HTTP 400 响应(您正在访问一个不知道 Socket.IO 会话的服务器)。
可以在 此处 找到更多信息。
Redis 服务器宕机时会发生什么?
如果与 Redis 服务器的连接断开,数据包将仅发送到连接到当前服务器的客户端。
从 socket.io-redis
迁移
该包已在 v7 中从 socket.io-redis
重命名为 @socket.io/redis-adapter
,以匹配 Redis 发射器 (@socket.io/redis-emitter
) 的名称。
要迁移到新包,您需要确保提供自己的 Redis 客户端,因为该包将不再代表用户创建 Redis 客户端。
之前
const redisAdapter = require("socket.io-redis");
io.adapter(redisAdapter({ host: "localhost", port: 6379 }));
之后
const { createClient } = require("redis");
const { createAdapter } = require("@socket.io/redis-adapter");
const pubClient = createClient({ url: "redis://localhost:6379" });
const subClient = pubClient.duplicate();
io.adapter(createAdapter(pubClient, subClient));
Socket.IO 服务器之间的通信协议尚未更新,因此您可以同时使用一些具有 socket.io-redis
的服务器和一些具有 @socket.io/redis-adapter
的服务器。
最新版本
版本 | 发布日期 | 发行说明 | 差异 |
---|---|---|---|
8.3.0 | 2024 年 3 月 | 链接 | 8.2.1...8.3.0 |
8.2.1 | 2023 年 5 月 | 链接 | 8.2.0...8.2.1 |
8.2.0 | 2023 年 5 月 | 链接 | 8.1.0...8.2.0 |
8.1.0 | 2023 年 2 月 | 链接 | 8.0.0...8.1.0 |
8.0.0 | 2022 年 12 月 | 链接 | 7.2.0...8.0.0 |
7.2.0 | 2022 年 5 月 | 链接 | 7.1.0...7.2.0 |
发射器
Redis 发射器允许从另一个 Node.js 进程向连接的客户端发送数据包


此发射器也以多种语言提供
- Javascript: https://github.com/socketio/socket.io-redis-emitter
- Java: https://github.com/sunsus/socket.io-java-emitter
- Python: https://pypi.ac.cn/project/socket.io-emitter/
- PHP: https://github.com/rase-/socket.io-php-emitter
- Golang: https://github.com/yosuke-furukawa/socket.io-go-emitter
- Perl: https://metacpan.org/pod/SocketIO::Emitter
- Rust: https://github.com/epli2/socketio-rust-emitter
安装
npm install @socket.io/redis-emitter redis
用法
import { Emitter } from "@socket.io/redis-emitter";
import { createClient } from "redis";
const redisClient = createClient({ url: "redis://localhost:6379" });
redisClient.connect().then(() => {
const emitter = new Emitter(redisClient);
setInterval(() => {
emitter.emit("time", new Date);
}, 5000);
});
注意: 使用 redis@3
时,无需在 Redis 客户端上调用 connect()
import { Emitter } from "@socket.io/redis-emitter";
import { createClient } from "redis";
const redisClient = createClient({ url: "redis://localhost:6379" });
const emitter = new Emitter(redisClient);
setInterval(() => {
emitter.emit("time", new Date);
}, 5000);
请参考 此处 的速查表。
从 socket.io-emitter
迁移
该包已在 v4 中从 socket.io-emitter
重命名为 @socket.io/redis-emitter
,以更好地反映与 Redis 的关系。
要迁移到新包,您需要确保提供自己的 Redis 客户端,因为该包将不再代表用户创建 Redis 客户端。
之前
const io = require("socket.io-emitter")({ host: "127.0.0.1", port: 6379 });
之后
const { Emitter } = require("@socket.io/redis-emitter");
const { createClient } = require("redis");
const redisClient = createClient();
const io = new Emitter(redisClient);
最新版本
版本 | 发布日期 | 发行说明 | 差异 |
---|---|---|---|
5.1.0 | 2023 年 1 月 | 链接 | 5.0.0...5.1.0 |
5.0.0 | 2022 年 9 月 | 链接 | 4.1.1...5.0.0 |
4.1.1 | 2022 年 1 月 | 链接 | 4.1.0...4.1.1 |
4.1.0 | 2021 年 5 月 | 链接 | 4.0.0...4.1.0 |
4.0.0 | 2021 年 3 月 | 链接 | 3.2.0...4.0.0 |