转到主要内容
Version: 4.x

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

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

安装

npm install @socket.io/redis-adapter redis

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

用法

import { Server } from "socket.io";
import { createAdapter } from "@socket.io/redis-adapter";
import { createClient } from "redis";

const io = new Server();

const pubClient = createClient({ url: "redis://localhost:6379" });
const subClient = pubClient.duplicate();

Promise.all([pubClient.connect(), subClient.connect()]).then(() => {
io.adapter(createAdapter(pubClient, subClient));
io.listen(3000);
});

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

import { Server } from "socket.io";
import { createAdapter } from "@socket.io/redis-adapter";
import { createClient } from "redis";

const io = new Server();

const pubClient = createClient({ url: "redis://localhost:6379" });
const subClient = pubClient.duplicate();

io.adapter(createAdapter(pubClient, subClient));
io.listen(3000);

或与ioredis

import { Server } from "socket.io";
import { createAdapter } from "@socket.io/redis-adapter";
import { Cluster } from "ioredis";

const io = new Server();

const pubClient = new Cluster([
{
host: "localhost",
port: 6380,
},
{
host: "localhost",
port: 6381,
},
]);

const subClient = pubClient.duplicate();

io.adapter(createAdapter(pubClient, subClient));
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 客户端。

之前:

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

最新版本

Emitter

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

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

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

安装

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,不需要connect()调用Redis 客户端:

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);

最新版本