Node.js 如何连接到现有的套接字io连接

Node.js 如何连接到现有的套接字io连接,node.js,socket.io,Node.js,Socket.io,我的应用程序是这样工作的: 用户登录到该网站 JavaScript连接到Socket.IO服务器,并传输PHPSESSID Socket.IO使用PHPSESSID连接到数据库,然后获取user\u id 使用user\u id我们将再次连接到数据库以获取user\u位置 然后,用户将连接到房间user\u place,并可以在这里与其他人交谈 问题是,user\u place可以通过另一个php脚本进行更改 因此,当它更改时,我需要告诉当前套接字io连接从数据库中获取新的“user\u pla

我的应用程序是这样工作的:

  • 用户登录到该网站
  • JavaScript连接到Socket.IO服务器,并传输PHPSESSID
  • Socket.IO使用PHPSESSID连接到数据库,然后获取
    user\u id
  • 使用
    user\u id
    我们将再次连接到数据库以获取
    user\u位置
  • 然后,用户将连接到房间
    user\u place
    ,并可以在这里与其他人交谈
  • 问题是,
    user\u place
    可以通过另一个php脚本进行更改

    因此,当它更改时,我需要告诉当前套接字io连接从数据库中获取新的“user\u place”,以便它可以离开当前房间并连接到新房间

    我怎样才能做到这一点

    我有两个猜测:

  • 执行php脚本时,连接到现有的Socket.IO连接并执行类似于
    client.on('update_place')、function(){}
    的代码问题是我不知道如何连接到现有连接(可能吗?)
  • 有一个setTimeout()函数,用于检查数据库上的constatly是否“user\u place”已更改(但性能会很差)
  • 以下是节点服务器的一些简化代码:

    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,但您可以采用另一种方式

    首先,创建一个对象,该对象将存储用户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\u place
    更改时,将POST请求发送到节点(例如,发送到
    http://127.0.0.1:1337/change_user_place
    )并向其传递
    用户id
    新位置
    参数

    在节点端,您可以使用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和新位置,节点就应该验证这个密码


    祝我好运,也为我的英语感到抱歉。

    非常感谢您的解释!它很完美,真的帮助了我。仅供参考,我计划使用Elephant.io()通过PHP连接到NodeJS。但是您这样做的方式允许我通过http发送数据,而且确实更简单、更快、更容易!再次感谢你,不客气,谢谢你的链接。由于我还必须在工作中结合使用PHP和Node.js,这可能对我很有用:)