socket.io namespaces and rooms (译)

前言

网上查阅了 socket.io  官方文档,彷佛没有发现最新的中文文档,有旧的,好比这个  (socket.io 中文文档)   是  2017 年的。redis

官网的实例和网上绝大多数入门例子,几乎都同样,就一个群聊窗口,过于简单。这让不少有志于socket.io 学习的人不那么方便,这里翻译一篇官网的 socket.io 关于 namespace 和rooms 的文档,但愿对你们有点帮助。如须要查阅的人多,再考虑翻译其它节。服务器

原文地址:Rooms and Namespaces异步

如下为译文socket

命名空间(namespace,如下简称ns)

socket.io 容许你将socket 制定不一样的命名空间,本质上,就是指定不一样的 终点(endpoint) 或 路径(path)tcp

这是个有用的特性,它能减小所需资源数目(tcp 链接数),同时,它经过隔离通讯信道(通道 channel)达到隔离应用的多个部分函数

默认命名空间

咱们使用默认命名空间 /  ,它既是socket.io 客户端默认链接也是服务端默认监听的的命名空间。
ns 经过 io.sockets 或 简以 io 调用加以区分:工具

// the following two will emit to all the sockets connected to `/`
io.sockets.emit('hi', 'everyone');
io.emit('hi', 'everyone'); // short form

每一个ns 都会触发一 connection 事件,并以 socket 做为参数传递到事件响应中学习

io.on('connection', function(socket){
  socket.on('disconnect', function(){ });
});

自定义命名空间

若是要设置一个自定义ns,你可再服务端调用 of 函数:ui

const nsp = io.of('/my-namespace');
nsp.on('connection', function(socket){
  console.log('someone connected');
});
nsp.emit('hi', 'everyone!');

在客户端,你能够告知 socket.io 客户端链接到对应的ns
const socket = io('/my-namespace');socket.io

重要提示:ns 仅是 socket.io 协议的实现细节,它和实际 URL 所表示的底层传输并没有关系,如: /socket.io/...

房间(rooms)

在每一个ns 内,你能够定义专属通道供, 这些sockets 能够 join 和 leave

Joining and leaving

你能够经过调用 join 函数 让 socket 订阅一个指定通道

io.on('connection', function(socket){
  socket.join('some room');
});

而后,在广播或者分发时能够简单的使用 to 或者 in (二者等同)
io.to('some room').emit('some event');
若是要离开通道,你能够像调用 join同样而调用 leave。 这两个方法都是异步的,接受 callback 做用参数

默认房间

在socket.io中,每一个socket都会以一个 随机的、不可测的惟一标识 socket#id 区分。 为了方便,每一个socket又会自动的经过这个标识id加入到一个房间。
这样让广播一个消息到其它sockets 很方便:

io.on('connection', function(socket){
  socket.on('say to someone', function(id, msg){
    socket.broadcast.to(id).emit('my message', msg);
  });
});

断开链接(disconnection)

对应链接断开,socket 或自动的 leave 全部通道,并不须要你作其它处理

从外部发送消息

有时,你可能须要在socket.io 进程上下文以外向你的 socket.io ns / rooms 中的sockets 分发事件
有一些方式能够处理这种问题,好比实现本身的通道从而向进程发送消息
为了简化此种状况,咱们建立了两个模块

  • socket.io-redis
  • socket.io-emitter

经过实践redis 适配器:

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

而后你就能从其余进程 emit 消息到任意通道

const io = require('socket.io-emitter')({ host: '127.0.0.1', port: 6379 });
setInterval(function(){
  io.emit('time', new Date);
}, 5000);

以上为翻译全文

后记

幸亏本节不长内容很少,翻译一个小时左右。对于文章尾部 “从进程外发送消息”,这个例子和说明不是很清晰,这里再补充下:

socket.io-redis 和 socket.io-emitter 是两个独立的模块,它们并不必定要组合使用。

对于实际的生产环境,咱们的socket.io 服务多是集群部署,使用多个进程或者在多个服务器,在某一进程 emit 如何让其它进程上的客户端也能收到? 此时 socket.io-redis 就是一有效工具,它经过 redis自己自带的 Pub/Sub 机制,达到也向其它进程上的客户端广播消息的目的。

而 socket.io-emmitter 才是彻底从其它非socket.io 进程发送消息到socket.io 进程所要依赖的,同时结合 socket.io-redis 使用。

相关文章
相关标签/搜索