您的位置:首页 > Web前端 > AngularJS

socket.io一对一通信的实现

2014-12-13 18:25 274 查看
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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息