通过socket.id发送消息给客户端

当他们的套接字ID已经被直接存储在io.sockets.on('connect')函数中时,我似乎只能向用户发送消息。 我不知道为什么当它们login后尝试存储它们的套接字ID是不行的。

加工:

var clients = {}; /** A new socket connection has been accepted */ io.sockets.on('connection', function (socket) { //Used to access session id var hs = socket.handshake; clients[socket.id] = socket; // add the client data to the hash users['brownj2'] = socket.id; // connected user with its socket.id socket.on('user-login', function(user){ if(!users[username]){ //users[username] = socket.id; // connected user with its socket.id } }) socket.on('page-load', function(pid) { if(users['brownj2']) { clients[users['brownj2']].emit('hello'); } else { console.log("NOT FOUND BROWNJ2"); } } } 

不工作:

  var clients = {}; /** A new socket connection has been accepted */ io.sockets.on('connection', function (socket) { //Used to access session id var hs = socket.handshake; clients[socket.id] = socket; // add the client data to the hash socket.on('user-login', function(user){ if(!users['brownj2']){ users['brownj2'] = socket.id; // connected user with its socket.id } }) socket.on('page-load', function(pid) { if(users['brownj2']) { clients[users['brownj2']].emit('hello'); } else { console.log("NOT FOUND BROWNJ2"); } } } 

JavaScript客户端代码片段

 var socket = io.connect(''); socket.on("hello", function(){ alert("Hi Jack"); console.log("WEBSOCKET RECIEVED"); }) 

解决scheme:感谢@alessioalex我不得不从login页面中删除对socket.io的引用,并将以下内容添加到io.sockets.on('连接')

 var hs = socket.handshake; sessionStore.get(hs.sessionID, function(err, session){ console.log("SESSION: " + util.inspect(session)); clients[socket.id] = socket; // add the client data to the hash validUsers[session.username] = socket.id; // connected user with its socket.id }) 

你的代码有一些问题,首先是你不应该通过Socket.IO来validation用户,你应该确保他们只有在通过身份validation之后才能连接。 如果您使用Express,那么下面的文章可以帮助您很多: http : //www.danielbaulig.de/socket-ioexpress/

你也应该避免像这样发送消息,因为这是Socket.IO内部的一部分,可能会改变:

 io.sockets.socket(id).emit('hello'); 

相反(如果你想发送一个消息到一个特定的客户端)最好保持一个对象,例如连接的客户端(并删除客户端一旦断开连接):

 // the clients hash stores the sockets // the users hash stores the username of the connected user and its socket.id io.sockets.on('connection', function (socket) { // get the handshake and the session object var hs = socket.handshake; users[hs.session.username] = socket.id; // connected user with its socket.id clients[socket.id] = socket; // add the client data to the hash ... socket.on('disconnect', function () { delete clients[socket.id]; // remove the client from the array delete users[hs.session.username]; // remove connected user & socket.id }); } // we want at some point to send a message to user 'alex' if (users['alex']) { // we get the socket.id for the user alex // and with that we can sent him a message using his socket (stored in clients) clients[users['alex']].emit("Hello Alex, how've you been"); } 

当然, io.sockets.socket(id)可以工作(实际上并没有testing),但它也可以随时更改,因为它是Socket.IO内部的一部分,所以我的解决scheme更安全。

你可能想在你的代码中改变客户端的另一件事是var socket = io.connect(''); var socket = io.connect('http://localhost'); ,正如我们在Socket.IO的官方例子中可以看到的那样: http ://socket.io/#how-to-use

我可以看到这个post产生了很多的兴趣…所以我要发布我用来实现这个的代码:

笔记

我已经使用Redis作为会话存储。 会话最初是通过包含用户详细信息的HTTP请求在login页面设置的,如果这些详细信息是有效的(根据MongoDB文档进行检查)…则创build会话。

服务器端代码创build和删除会话/套接字

 //Auth the user io.set('authorization', function (data, accept) { // check if there's a cookie header if (data.headers.cookie) { data.cookie = parseCookie(data.headers.cookie); data.sessionID = data.cookie['express.sid']; //Save the session store to the data object data.sessionStore = sessionStore; sessionStore.get(data.sessionID, function(err, session){ if(err) throw err; if(!session) { console.error("Error whilst authorizing websocket handshake"); accept('Error', false); } else { console.log("AUTH USERNAME: " + session.username); if(session.username){ data.session = new Session(data, session); accept(null, true); }else { accept('Invalid User', false); } } }) } else { console.error("No cookie was found whilst authorizing websocket handshake"); return accept('No cookie transmitted.', false); } }); /** A new socket connection has been accepted */ io.sockets.on('connection', function (socket) { var hs = socket.handshake; if(hs.session) { if(hs.session.username) { clients[socket.id] = socket; // add the client data to the hash validUsers[hs.session.username] = socket.id; // connected user with its socket.id } } socket.on('disconnect', function() { delete browsing[hs.session.username]; //Remove the client from the browsing hash delete clients[socket.id]; // remove the client from the array delete validUsers[hs.session.username]; // remove connected user & socket.id }) .... } 

服务器端select性消息发送

这段代码允许我发送消息给项目的团队成员。 一组用户将不会收到来自单独的用户组的消息。

 for(var i = 0; i < project.team.length; i++) { if(validUsers[project.team[i].username]) { if(clients[validUsers[project.team[i].username]]) { projects.update({"_id" : projectId}, {"$pull" : {"stories" : {"_id" : storyId}} } ); clients[validUsers[project.team[i].username]].emit('delete-story', storyId); } else { console.error("Project team member not found"); } } }