Redis 适配器

这个怎么运作

Redis 适配器依赖于 Redis Pub/Sub 机制

每个发送给多个客户的数据包(例如: io.to("room1").emit()socket.broadcast.emit())是:

  • 发送到连接到当前服务器的所有匹配客户端
  • 在 Redis 通道中发布,并由集群的其他 Socket.IO 服务器接收

Diagram of how the Redis adapter worksDiagram of how the Redis adapter works

这个适配器的源代码可以在这里找到。

安装

  1. npm install @socket.io/redis-adapter redis

对于 TypeScript 用户,@types/redis如果您使用的是redis@3

用法

  1. import { Server } from "socket.io";
  2. import { createAdapter } from "@socket.io/redis-adapter";
  3. import { createClient } from "redis";
  4. const io = new Server();
  5. const pubClient = createClient({ url: "redis://localhost:6379" });
  6. const subClient = pubClient.duplicate();
  7. Promise.all([pubClient.connect(), subClient.connect()]).then(() => {
  8. io.adapter(createAdapter(pubClient, subClient));
  9. io.listen(3000);
  10. });

注意:使用redis@3,不需要connect()调用Redis 客户端:

  1. import { Server } from "socket.io";
  2. import { createAdapter } from "@socket.io/redis-adapter";
  3. import { createClient } from "redis";
  4. const io = new Server();
  5. const pubClient = createClient({ url: "redis://localhost:6379" });
  6. const subClient = pubClient.duplicate();
  7. io.adapter(createAdapter(pubClient, subClient));
  8. io.listen(3000);

或与ioredis

  1. import { Server } from "socket.io";
  2. import { createAdapter } from "@socket.io/redis-adapter";
  3. import { Cluster } from "ioredis";
  4. const io = new Server();
  5. const pubClient = new Cluster([
  6. {
  7. host: "localhost",
  8. port: 6380,
  9. },
  10. {
  11. host: "localhost",
  12. port: 6381,
  13. },
  14. ]);
  15. const subClient = pubClient.duplicate();
  16. io.adapter(createAdapter(pubClient, subClient));
  17. io.listen(3000);

配置

配置项描述Default 默认值
keyPub/Sub频道名称的前缀socket.io
requestsTimeout服务器间请求的超时时间,例如fetchSockets()serverSideEmit()5000

常见问题

  • 使用 Redis 适配器时是否还需要启用粘性会话?

是的。否则将导致 HTTP 400 响应(您到达的服务器不知道 Socket.IO 会话)。

更多信息可以在这里找到。

  • Redis 服务器宕机时会发生什么?

如果与 Redis 服务器的连接被切断,数据包将仅发送到连接到当前服务器的客户端。

迁移自 socket.io-redis

为了匹配 Redis 发射器 (@socket.io/redis-emitter)的名称,该包在v7中被重命名从 socket.io-redis 变成 @socket.io/redis-adapter

要迁移到新包,您需要确保提供自己的 Redis 客户端,因为该包将不再代表用户创建 Redis 客户端。

之前:

  1. const redisAdapter = require("socket.io-redis");
  2. io.adapter(redisAdapter({ host: "localhost", port: 6379 }));

现在:

  1. const { createClient } = require("redis");
  2. const { createAdapter } = require("@socket.io/redis-adapter");
  3. const pubClient = createClient({ url: "redis://localhost:6379" });
  4. const subClient = pubClient.duplicate();
  5. io.adapter(createAdapter(pubClient, subClient));

Redis 适配器 - 图3笔记

Socket.IO 服务器之间的通信协议尚未更新,因此您可以同时拥有一些服务器socket.io-redis和一些其他服务器 @socket.io/redis-adapter

最新版本

Emitter

Redis 发射器允许从另一个 Node.js 进程向连接的客户端发送数据包:

Diagram of how the Redis emitter worksDiagram of how the Redis emitter works

此发射器还提供多种语言版本:

安装

  1. npm install @socket.io/redis-emitter redis

用法

  1. import { Emitter } from "@socket.io/redis-emitter";
  2. import { createClient } from "redis";
  3. const redisClient = createClient({ url: "redis://localhost:6379" });
  4. redisClient.connect().then(() => {
  5. const emitter = new Emitter(redisClient);
  6. setInterval(() => {
  7. emitter.emit("time", new Date);
  8. }, 5000);
  9. });

注意:使用redis@3,不需要connect()调用Redis 客户端:

  1. import { Emitter } from "@socket.io/redis-emitter";
  2. import { createClient } from "redis";
  3. const redisClient = createClient({ url: "redis://localhost:6379" });
  4. const emitter = new Emitter(redisClient);
  5. setInterval(() => {
  6. emitter.emit("time", new Date);
  7. }, 5000);

请参阅此处的备忘单。

迁移自 socket.io-emitter

v4中,改包从socket.io-emitter重命名为@socket.io/redis-emitter以更好地体现与 Redis 的关系。

要迁移到新包,您需要确保提供自己的 Redis 客户端,因为该包将不再代表用户创建 Redis 客户端。

之前:

  1. const io = require("socket.io-emitter")({ host: "127.0.0.1", port: 6379 });

现在:

  1. const { Emitter } = require("@socket.io/redis-emitter");
  2. const { createClient } = require("redis");
  3. const redisClient = createClient();
  4. const io = new Emitter(redisClient);

最新版本