命名空间
Socket.IO allows you to “namespace” your sockets, which essentially means assigning different endpoints or paths.
This is a useful feature to minimize the number of resources (TCP connections) and at the same time separate concerns within your application by introducing separation between communication channels.
默认命名空间
We call the default namespace / and it’s the one Socket.IO clients connect to by default, and the one the server listens to by default.
This namespace is identified by io.sockets or simply io:
// the following two will emit to all the sockets connected to `/`
io.sockets.emit('hi', 'everyone');
io.emit('hi', 'everyone'); // short form
Each namespace emits a connection event that receives each Socket instance as a parameter
io.on('connection', function(socket){
socket.on('disconnect', function(){ });
});
自定义命名空间
To set up a custom namespace, you can call the of function on the server-side:
var nsp = io.of('/my-namespace');
nsp.on('connection', function(socket){
console.log('someone connected'):
});
nsp.emit('hi', 'everyone!');
On the client side, you tell Socket.IO client to connect to that namespace:
var socket = io('/my-namespace');
重要说明: The namespace is an implementation detail of the Socket.IO protocol, and is not related to the actual URL of the underlying transport, which defaults to /socket.io/….
房间
Within each namespace, you can also define arbitrary channels that sockets can join and leave.
加入和离开
You can call join to subscribe the socket to a given channel:
io.on('connection', function(socket){
socket.join('some room');
});
And then simply use to or in (they are the same) when broadcasting or emitting:
io.to('some room').emit('some event'):
To leave a channel you call leave in the same fashion as join.
默认房间
Each Socket in Socket.IO is identified by a random, unguessable, unique identifier Socket#id. For your convenience, each socket automatically joins a room identified by this id.
This makes it easy to broadcast messages to other sockets:
io.on('connection', function(socket){
socket.on('say to someone', function(id, msg){
socket.broadcast.to(id).emit('my message', msg);
});
});
断开连接
Upon disconnection, sockets leave all the channels they were part of automatically, and no specially teardown is needed on your part.
从外部世界发送消息
In some cases, you might want to emit events to sockets in Socket.IO namespaces / rooms from outside the context of your Socket.IO processes.
There’s several ways to tackle this problem, like implementing your own channel to send messages into the process.
To facilitate this use case, we created two modules:
- socket.io-redis
- socket.io-emitter
By implementing the Redis Adapter:
var io = require('socket.io')(3000);
var redis = require('socket.io-redis');
io.adapter(redis({ host: 'localhost', port: 6379 }));
you can then emit messages from any other process to any channel
var io = require('socket.io-emitter')();
setInterval(function(){
io.emit('time', new Date);
}, 5000);