因为我的能力,所写内容较为懒散,请多见谅。javascript
若排版乱掉,请参阅https://www.zybuluo.com/bornkiller/note/6163前端
若有错误,联系QQ:491229492,收到反馈后会尽快修正。java
// send to current request socket client socket.emit('message', "this is a test"); // sending to all clients except sender socket.broadcast.emit('message', "this is a test"); // sending to all clients in 'game' room(channel) except sender socket.broadcast.to('game').emit('message', 'nice game'); // sending to all clients, include sender io.sockets.emit('message', "this is a test"); // sending to all clients in 'game' room(channel), include sender io.sockets.in('game').emit('message', 'cool game'); // sending to individual socketid io.sockets.socket(socketid).emit('message', 'for your eyes only');
上述集中方式为socket.io经常使用的数据传输方式,node
io.sockets.on('connection', function (socket) { });
回调函数的socket参数为一个client
与服务器的链接标示,不一样的client
会有不一样的链接标示。web
socket.emitsocket.emit
信息传输对象为当前socket
对应的client
,各个client socket
相互不影响。redis
socket.broadcast.emitsocket.broadcast.emit
信息传输对象为全部client
,排除当前socket
对应的client
。chrome
io.sockets.emit
信息传输对象为全部client
。数组
相似于以前提过的of
方法生成命名空间来管理用户,socket.io
可使用分组方法,socket.join()
,以及与之对应的socket.leave()
。服务器
io.sockets.on('connection', function (socket) { socket.on('firefox', function (data) { socket.join('firefox'); }); socket.on('chrome',function(data){ socket.join('chrome'); }); });
假设有两个聊天室,一个名为firefox,另外一个为chrome,客户端操做websocket
socket.emit('firefox')
,就能够加入firefox
聊天室;socket.emit('chrome')
,就能够加入chrome
聊天室;
向一个分组传输消息,有两种方式:
socket.broadcast.to('chrome').emit('event_name', data); //emit to 'room' except this socket client io.sockets.in('chrome').emit('event_name', data) //emit to all socket client in the room
broadcast
方法容许当前socket client
不在该分组内。
可能有一个疑问,一个socket
是否能够同时存在于几个分组,等效于一个用户会同时在几个聊天室活跃,答案是”能够“,socket.join()
添加进去就能够了。官方提供了订阅模式的示例:
socket.on('subscribe', function(data) { socket.join(data.room); }) socket.on('unsubscribe', function(data) { socket.leave(data.room); })
后台处理订阅/退订事件
socket = io.connect('http://127.0.0.1:1338/'); socket.emit('subscribe',{"room" : "chrome"}; socket.emit('unsubscribe',{"room" : "chrome"};
前端触发订阅/退订事件,就能够加入对应的聊天室。 经过of
方法也能够经过划分命名空间的方式,实现聊天室功能,但不如分组管理来的方便。
socket
链接须要添加权限验证,让已登陆的用户socket
链接到服务器,未登陆的用户无条件拒绝。全局受权管理以下:io.sockets.authorization(function (handshakeData, callback) { callback(null, true); }).
callback
函数有两个参数,第一个为error
,第二个参数为是否受权bool值,经过受权回调函数应为callback(null,true)
,其它状况下都为拒绝创建链接。
按照web的开发方式,检测是否登陆首选cookie-session
来实现,问题也是出在这里。websocket
握手阶段属于HTTP
协议,简单来讲是能够读到cookie,就能够实现session。
// sending to individual socketid io.sockets.socket(socketid).emit('message', 'for your eyes only');
就能够向一个特定用户推送消息,可是如何得到这个socketId
,就是生成一个哈希数组,key为username,值为socket.id,这样就能够经过用户名获取对应的id,进而能够向特定client推送消息。
因为我将Express框架和socket.io库两个进程,并且没有使用redis共享数据,因此暂时不能作到session
读取,大概5天后补上。