如何连接到现有的套接字io连接

我的应用程序这样工作:

  1. 用户login到网站
  2. JavaScript连接到Socket.IO服务器,并传输PHPSESSID
  3. Socket.IO使用PHPSESSID连接到数据库,然后获取user_id
  4. 使用user_id我们再连接一次数据库来获取user_place
  5. 用户然后连接到房间user_place并可以在这里与其他人交谈

事情是, user_place可以通过,例如,另一个PHP脚本更改。

所以当它改变的时候, 我需要告诉当前套接字io连接从数据库中获取新的“user_place” ,所以它可以离开当前房间并连接到新的。

我怎样才能做到这一点?

我有两个猜测:

  1. 执行php脚本时,连接到现有的Socket.IO连接并执行如client.on('update_place'), function() {}问题是我不知道如何连接到一个现有的连接 (是否有可能?)
  2. 有一个setTimeout()函数检查数据库是否“user_place”已更改或不(但perfs将是可怕的)

以下是节点服务器的一些简化代码:

 io.sockets.on('connection', function(client) { var user_place; // Read client cookies if(client.handshake.headers['cookie']) { var cookies = cookie.parse(client.handshake.headers['cookie']); } // If cookies exist, connect to database and get “user_place” if(cookies) { connection.query("SELECT session_value, session_time FROM sessions WHERE session_id = ?", [cookies.PHPSESSID], function(err, rows, fields) { if(rows[0]) { var session_value_json = JSON.parse(atob(rows[0].session_value)); user_id = session_value.user_id; if(user_id) { connection.query( "SELECT place FROM users WHERE id = ?", [user_id], function(err, rows, fields) { // Set data user_place user_place = rows[0].user_place; // Join the room client.join(user_place); }); } } }); } // Chatting... client.on('message', function (data) { io.sockets.in(user_place).emit('message', { user_id : user_id, message_content : data.message } ); }); }); 

我怀疑你可以从PHP连接到Socket.IO,但你可以换一种方式。

首先,创build一个将存储用户ID和套接字ID之间关系的对象:

 var userSocketIds = {}; io.sockets.on('connection', function(client) { ... connection.query( "SELECT place FROM users WHERE id = ?", [user_id], function(err, rows, fields) { // Set data user_place user_place = rows[0].user_place; // Join the room client.join(user_place); userSocketIds[user_id] = client.id; client.on('disconnect', function() { delete userSocketIds[user_id]; //collect garbage }); }); ... }); 

因此,如果你知道用户ID,你可以得到这样的Socket.IO客户端ID:

 var clientId = userSocketIds[user_id]; 

然后,当user_place被更改时,发送POST请求到节点(例如,到http://127.0.0.1:1337/change_user_place )并传递user_idnew_place参数给它。

在节点端,您可以使用Express处理这些请求并更改用户的房间:

 app.post('/change_user_place', function(req, res) { var clientId = userSocketIds[req.body.user_id]; if (clientId && io.sockets.connected[clientId]) { io.sockets.connected[clientId].join(req.body.new_place); //join user to new_place } }); 

当然,你也可以发送GET请求,而不是POST (而且实现起来会更容易一些 – 你不需要安装body-parser中间件),但是在服务器端改变一些东西的时候,最好使用POST方法。 检查这个 。

你也可以(也应该)实现诸如密码授权之类的东西。 很简单:您的PHP脚本只需要传递一些密码以及用户ID和新位置,节点应该validation此密码。

祝你好运,并为我的英语感到难过。