socket.io-redis 文档翻译

0.455字数 858阅读 2963

socket.io-redis

如何去使用

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

通过使用socket.io-redis 适配器运行socket.io 你可以在不同的进程或者服务器上运行多个socket.io实例,这样可以每个客户端广播和发送事件。

下面是一些命令:

io.emit('hello', '给所有客户端发送');
io.to('room42').emit('hello', "给所有在'room42'房间的客户端发送");

io.on('connection', (socket) => {
  socket.broadcast.emit('hello', '给所有除了发送者的客户端发送');
  socket.to('room42').emit('hello', "给所有在'room42'房间除了发送者的客户端发送");
});

将通过Redis 订阅/发布机制,给客户端广播

如果你想通过非socket.io进程向socket.io广播,你需要使用socket.io-emitter.

API

adapter(uri[, opts])

uri 是一个类似 localhost:6379 的字符串,如果你的 redis 是本地的. 下面列出了一些配置项

adapter(opts)

下列是被允许的配置项:

  • key: 订阅/发布事件的key的名称,比如(socket.io)
  • host: 连接redis的主机 (localhost)
  • port: 连接redis的端口(6379)
  • pubClient: 可选的, redis客户端的发布事件
  • subClient: 可选的, redis客户端的订阅时间
  • requestsTimeout: 可选的, 超时后适配器将停止响应请求(5000ms)

如果你决定提供pubClientsubClient, 确定你使用make sure you use
node_redis 作为客户端或者一个同等的API

RedisAdapter

redis适配器实例暴露了下面的属性,这是一般 适配器 所没有的

  • uid
  • prefix
  • pubClient
  • subClient
  • requestsTimeout

RedisAdapter#clients(rooms:Array, fn:Function)

返回连接房间名为rooms 的所有节点的客户端ID列表.查看 Namespace#clients(fn:Function)

io.of('/').adapter.clients((err, clients) => {
  console.log(clients); // 一个包含所有连接上的客户端id的数组
});

io.of('/').adapter.clients(['room1', 'room2'], (err, clients) => {
  console.log(clients); // 一个包括了房间名为'room1' 和/或 'room2'的客户端id的数组
});

// 你也可以这样用
io.in('room3').clients((err, clients) => {
  console.log(clients); // 一个包括了'room3'房间内所有客户端id的数组
});

RedisAdapter#clientRooms(id:String, fn:Function)

返回给定客户端ID加入的房间的列表(甚至是在其他节点).

io.of('/').adapter.clientRooms('<my-id>', (err, rooms) => {
  if (err) { /* 未知 id */ }
  console.log(rooms); // 一个包含所给id的客户端加入的所有房间的数组
});

RedisAdapter#allRooms(fn:Function)

返回包含所有房间的列表

io.of('/').adapter.allRooms((err, rooms) => {
  console.log(rooms); // 一个包括所有房间的数组 (所有节点)
});

RedisAdapter#remoteJoin(id:String, room:String, fn:Function)

让socket给定的id加入房间。回调将在socket加入到房间后触发,否则如果没有找到socket客户端,会提供一个err 参数

io.of('/').adapter.remoteJoin('<my-id>', 'room1', (err) => {
  if (err) { /* 未知 id */ }
  // 成功
});

RedisAdapter#remoteLeave(id:String, room:String, fn:Function)

使给定socketid的客户端离开房间。回调将在客户端离开房间后触发,如果没找到socket客户端,则会返回一个arr参数.

io.of('/').adapter.remoteLeave('<my-id>', 'room1', (err) => {
  if (err) { /* 未知的 id */ }
  // 成功
});

RedisAdapter#remoteDisconnect(id:String, close:Boolean, fn:Function)

使给定id的socket客户端断开连接M. 如果将 close 设置为true, 它也将关闭其底层等socket。回调将会在socket客户端断开连接后调用,如果socket客户端没找到,则会返回一个 err 参数.

io.of('/').adapter.remoteDisconnect('<my-id>', true, (err) => {
  if (err) { /* 未知的 id */ }
  // 成功
});

RedisAdapter#customRequest(data:Object, fn:Function)

给所有节点发送一个请求,将会通过 customHook 的方法响应.

// 所有节点
io.of('/').adapter.customHook = (data, cb) => {
  cb('hello ' + data);
}

// 之后
io.of('/').adapter.customRequest('john', function(err, replies){
  console.log(replies); // an array ['hello john', ...] with one element per node
});

客户端错误处理

接收Redis适配器实例的 pubClientsubClient 属性来订阅它的'error'时间:

const adapter = require('socket.io-redis')('localhost:6379');
adapter.pubClient.on('error', function(){});
adapter.subClient.on('error', function(){});

pubClientsubClient发布的错误,也将被转发到适配器实例:

const io = require('socket.io')(3000);
const redisAdapter = require('socket.io-redis');
io.adapter(redisAdapter({ host: 'localhost', port: 6379 }));
io.of('/').adapter.on('error', function(){});

自定义 client (例如: with authentication)

如果你需要给一个redis实例创建一个有密码的redisAdapter,
that has a password, 使用订阅/发布属性代替密码

const redis = require('redis');
const redisAdapter = require('socket.io-redis');
const pub = redis.createClient(port, host, { auth_pass: "pwd" });
const sub = redis.createClient(port, host, { auth_pass: "pwd" });
io.adapter(redisAdapter({ pubClient: pub, subClient: sub }));

With ioredis client

集群例子

const io = require('socket.io')(3000);
const Redis = require('ioredis');

const cluster = new Redis.Cluster([
  {
    port: 6380,
    host: '127.0.0.1'
  },
  {
    port: 6381,
    host: '127.0.0.1'
  }
]);

const redisAdapter = require('socket.io-redis');
io.adapter(redisAdapter({ pubClient: cluster, subClient: cluster }));

哨兵例子

const io = require('socket.io')(3000);
const Redis = require('ioredis');

const options = {
  sentinels: [
    { host: 'somehost1', port: 26379 },
    { host: 'somehost2', port: 26379 }
  ],
  name: 'master01'
};

const pubClient = new Redis(options);
const subClient = new Redis(options);

io.adapter(redisAdapter({ pubClient: options, subClient: options }));

协议

socket.io-redis 适配器 在特别命名的Redis通道上广播和接受信息。全局等广播通道名称为:

prefix + '#' + namespace + '#'

给单个房间广播的通道命名为:

prefix + '#' + namespace + '#' + room + '#'

还有其他的库采用这个协议:

License

MIT

推荐阅读更多精彩内容