如何连接到现有的套接字io连接
我的应用程序这样工作:
- 用户login到网站
- JavaScript连接到Socket.IO服务器,并传输PHPSESSID
- Socket.IO使用PHPSESSID连接到数据库,然后获取
user_id
- 使用
user_id
我们再连接一次数据库来获取user_place
- 用户然后连接到房间
user_place
并可以在这里与其他人交谈
事情是, user_place
可以通过,例如,另一个PHP脚本更改。
所以当它改变的时候, 我需要告诉当前套接字io连接从数据库中获取新的“user_place” ,所以它可以离开当前房间并连接到新的。
我怎样才能做到这一点?
我有两个猜测:
- 执行php脚本时,连接到现有的Socket.IO连接并执行如
client.on('update_place'), function() {}
。 问题是我不知道如何连接到一个现有的连接 (是否有可能?) - 有一个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_id
和new_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此密码。
祝你好运,并为我的英语感到难过。