socket.io一对一通信的实现

socket.io网上有很多例子,但是大多数都是聊天室的,没有找到一对一通信的例子

百度搜索了一下,在oschina里面看到了一篇文章http://www.oschina.net/question/190778_164263?sort=time

给了一点思路,就是每次用户连上socket的时候,保存一个id映射到socket对象的键值对

然后在每次emit新消息的时候,根据客户端传来的id,获取对应的socket对象,用这个对象emit信息,就可以实现一对一通信了

下面贴一下我的关键实现代码,代码基于上次发的文章的代码https://github.com/xyc-cn/socket-angular/tree/xyc_3

1.首先得在socket验证登陆的时候,把user对象传进来,前提是你在req.session.user里面添加了你的user对象

var io= require("socket.io").listen(app.listen(8000));
io.set('authorization', function(handshakeData, accept) {
     var cookies = cookie.parse(handshakeData.headers.cookie);
     var connectSid = cookies['connect.sid'];
     if(connectSid){
     var connected = cookieParser.signedCookie(connectSid, 'technode');
     if(connected){
     sessionStore.get(connected, function (error, session) {
     if (error) {
     accept(error.message, false)
     } else {
     handshakeData.headers.sessions  = session;//根据connectSid找session如果session对象不为空,把session对象添加到socket的headers里面
     if (session.user) {
     accept(null, true)
     } else {
     accept(null,false)
         }
     }
     })
 }else {
    accept(null,false)
    }
 }

 });
2.在socket链接的时候,我在客户端emit了init,在服务端保存id映射到socket对象的键值对
var loginUser = new Object();
socket.on('init', function () {
        socket.emit('init', messages);
        if(socket.handshake.headers.sessions!=null){//如果sessions不为空,取出里面保存的user对象
            var user = socket.handshake.headers.sessions.user;
            loginUser[user._id] = socket;//建立id映射到socket对象的键值对
            UserModel.modify({account:user.account},{status:1},function(err,doc){//这部分是我获取在线用户的代码
                UserModel.User.find({status:1},{account:1}, function (err,doc) {
                    if(doc){
                        io.sockets.emit('users.init', doc);
                    }
                });
            });

        }
    });
3.新建消息的时候,客户端传来一个belong,告诉服务端,这条消息是属于哪两个人的,这个值必须是唯一的,我是把两个通信的人的ID加起来生成这个值,然后还要传来to告诉服务器这个消息是发给谁的,from告诉服务器这个信息是谁发出来的

socket.on('messages.create', function (message) {
        var data ={};
        data.content = message.content;
        data.account = message.account;
        data.belong = message.belong;
        var to= message.to;

        MessageModel.create(data,function (err,doc) {//新建数据库条目
            if(!err){
                socket.emit('messages.add',doc,to,message.from);//emit通知自己,在发送方的窗口新增他自己发送的消息
                if(loginUser[to]!=null){//根据to值,选择对应的socket对象
                    loginUser[to].emit('messages.add', doc,to,message.from);//如果找到了这个对象,就emit信息给这个socket对象的链接客户端,传递信息
                }
            }
        });
    });
4.客户端读取信息的时候,要传来一个belong值,告诉服务端读取哪些聊天记录

 socket.on('messages.read', function (belong) {
        MessageModel.getMessage(new Date(),belong,function(err,doc){//根据传来的belong值,获取对应的聊天记录
            socket.emit('messages.read', doc);
        });
    });
5.链接断开的时候,清空数据

socket.on('disconnect', function() {
        if(socket.handshake.headers.sessions!=null) {
            var user = socket.handshake.headers.sessions.user;
            loginUser[user.id]=null;//清空对应的键值对
            UserModel.modify({account: user.account}, {status: 0}, function (err, doc) {//用户状态设置为下线
                if (doc != null) {
                    console.log(doc.account + " has disconnect");
                }
            });
            socket.broadcast.emit('users.remove', user);
        }
    });

整个项目的代码在https://github.com/xyc-cn/socket-angular/tree/xyc_4

有问题或者建议欢迎Q我278255596



  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值