通过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"); } } }