[关闭]
@bornkiller 2014-07-15T10:03:24.000000Z 字数 2587 阅读 11010

socket.io学习笔记

socket.io nodejs

由于个人能力,所写内容较为懒散,请多见谅。

服务器信息传输

  1. // send to current request socket client
  2. socket.emit('message', "this is a test");
  3. // sending to all clients except sender
  4. socket.broadcast.emit('message', "this is a test");
  5. // sending to all clients in 'game' room(channel) except sender
  6. socket.broadcast.to('game').emit('message', 'nice game');
  7. // sending to all clients, include sender
  8. io.sockets.emit('message', "this is a test");
  9. // sending to all clients in 'game' room(channel), include sender
  10. io.sockets.in('game').emit('message', 'cool game');
  11. // sending to individual socketid
  12. io.sockets.socket(socketid).emit('message', 'for your eyes only');

上述集中方式为socket.io常用的数据传输方式,

  1. io.sockets.on('connection', function (socket) {
  2. });

回调函数的socket参数为一个client与服务器的连接标示,不同的client会有不同的连接标示。

不分组,数据传输

分组数据传输

类似于之前提过的of方法生成命名空间来管理用户,socket.io可以使用分组方法,socket.join(),以及与之对应的socket.leave()

  1. io.sockets.on('connection', function (socket) {
  2. socket.on('firefox', function (data) {
  3. socket.join('firefox');
  4. });
  5. socket.on('chrome',function(data){
  6. socket.join('chrome');
  7. });
  8. });

假设有两个聊天室,一个名为firefox,另一个为chrome,客户端操作

socket.emit('firefox'),就可以加入firefox聊天室;
socket.emit('chrome'),就可以加入chrome聊天室;

向一个分组传输消息,有两种方式:

  1. socket.broadcast.to('chrome').emit('event_name', data);
  2. //emit to 'room' except this socket client
  3. io.sockets.in('chrome').emit('event_name', data)
  4. //emit to all socket client in the room

broadcast方法允许当前socket client不在该分组内。

可能有一个疑问,一个socket是否可以同时存在于几个分组,等效于一个用户会同时在几个聊天室活跃,答案是”可以“,socket.join()添加进去就可以了。官方提供了订阅模式的示例:

  1. socket.on('subscribe', function(data) {
  2. socket.join(data.room);
  3. })
  4. socket.on('unsubscribe', function(data) {
  5. socket.leave(data.room);
  6. })

后台处理订阅/退订事件

  1. socket = io.connect('http://127.0.0.1:1338/');
  2. socket.emit('subscribe',{"room" : "chrome"};
  3. socket.emit('unsubscribe',{"room" : "chrome"};

前端触发订阅/退订事件,就可以加入对应的聊天室。 通过of方法也可以通过划分命名空间的方式,实现聊天室功能,但不如分组管理来的方便。

Socket.io难点大放送(暂时没有搞定)

  1. io.sockets.authorization(function (handshakeData, callback) {
  2. callback(null, true);
  3. }).

callback函数有两个参数,第一个为error,第二个参数为是否授权bool值,通过授权回调函数应为callback(null,true),其它情况下都为拒绝建立连接。

按照web的开发方式,检测是否登录首选cookie-session来实现,问题也是出在这里。websocket握手阶段属于HTTP协议,简单来说是可以读到cookie,就可以实现session。
+ 精准单用户推送
理论上来说

  1. // sending to individual socketid
  2. io.sockets.socket(socketid).emit('message', 'for your eyes only');

就可以向一个特定用户推送消息,但是如何获得这个socketId,就是生成一个哈希数组,key为username,值为socket.id,这样就可以通过用户名获取对应的id,进而可以向特定client推送消息。

由于我将Express框架和socket.io库两个进程,而且没有使用redis共享数据,所以暂时不能做到session读取,大概5天后补上。

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注