Namespaces

命名空间

Socket.IO 允许为 socket 添加命名空间,也就是分配不同的路径

这可以最小化资源数量 (TCP 连接),并为应用提供频道划分功能。

默认命名空间

默认的命名空间是/,Socket.IO 客户端默认连接到这个命名空间,服务端默认监听的也是这个命名空间。

这个命名空间使用io.socketsio来标识:

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

每个命名空间都会触发一个 connection 事件。该事件接收一个 Socket 实例作为参数。

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

自定义命名空间

要使用自定义命名空间,可以在服务端调用of函数:

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

客户端使用如下方法连接到该命名空间:

var socket = io('/my-namespace'

重要提示:命名空间是 Socket.IO 协议的一个实现细节, 与底层传输的实际 URL 无关。底层传输的实际 URL 默认是/socket.io/…

空间频道

对于每个命名空间,你还可以定义任意频道。 sockets 可以joinleave该频道。

加入和离开

调用join可以订阅特定频道:

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

通过to或者in(它们是等效的) 可以在频道内广播或发送消息:

io.to('some room').emit('some event'):

调用leave可以离开空间,和join方法一样。

默认空间

Socket.IO 中的每个Socket都使用一个随机、不可预测、唯一的Socket#id标识符来标识。为了简便,每个 socket 自动进入一个使用自身 id 标识的房间。

这使得广播消息很容易:

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

断开连接

断开连接时, sockets 会自动leave所有频道,不需要你做任何处理。

使用外部消息源

对于一些场景,你可能需要从 Socket.IO 进程之外的的环境触发事件,以传递消息给 Socket.IO 命名空间 / 房间内的 sockets。

有多个方法处理这个问题,比如实现自定义的频道来为进程传入消息。

针对这种场景,我们创建了两个模块:

通过实现 RedisAdapter

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

你可以从任意进程emit消息给任意频道:

var io = require('socket.io-emitter')( setInterval(function(){ io.emit('time', new Date }, 5000