Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/361.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 无法发送到特定客户端:Socket IO会将其发送到每个客户端吗?_Javascript_Node.js_Express_Socket.io - Fatal编程技术网

Javascript 无法发送到特定客户端:Socket IO会将其发送到每个客户端吗?

Javascript 无法发送到特定客户端:Socket IO会将其发送到每个客户端吗?,javascript,node.js,express,socket.io,Javascript,Node.js,Express,Socket.io,是的,我已经阅读了文档,文档写得很好: 问题是:当用户从Express应用程序的会话被破坏时,我想通知用户注销。现在发生了这样的事情:当我从会话中注销时,所有其他客户端(包括那些已登录或尚未登录的客户端)都会收到一条消息,说他们已注销。是的,我的express应用程序工作正常-他们没有被注销,但我相信SOCKET IO正在向他们发送消息。我运行了调试器,结果发现这两个客户端也是可以区分的 这是我的密码: server.js: var app = express(); var server =

是的,我已经阅读了文档,文档写得很好:

问题是:当用户从Express应用程序的会话被破坏时,我想通知用户注销。现在发生了这样的事情:当我从会话中注销时,所有其他客户端(包括那些已登录或尚未登录的客户端)都会收到一条消息,说他们已注销。是的,我的express应用程序工作正常-他们没有被注销,但我相信SOCKET IO正在向他们发送消息。我运行了调试器,结果发现这两个客户端也是可以区分的

这是我的密码:

server.js:

var app = express();
var server = require('http').Server(app);
var io = require('socket.io')(server);
app.set('socketio', io);
io.on('connection', function (socket) {
  app.set('current_socket', socket);
  console.log('No of clients:', io.engine.clientsCount); 
});
userController.js:

exports.userLogout = function(req, res, next) {
    const sessionID = req.session.id;
    const io = req.app.get('socketio');
    const this_socket = req.app.get('current_socket');

    req.session.destroy(function (err){
        if(err) {
            console.error("userLogout failed with error:", err);
            return next(err);
        }
        else {
            console.log("this_socket:", this_socket);
            console.log("io:", io);
            this_socket.emit('userAction', { action: 'logout' });
            //other logic to remove old sessions from DB Session Store
            //and finally:
            res.status(200)
                .json({
                status: 'success',
                api_data: {'loggedIn':false},
                message: 'Logout successful.'
                });
        }
    }
}
exports.userLogout = function(req, res, next) {
    const sessionID = req.session.id;
    const io = req.app.get('socketio');
    const this_socket = req.app.get('current_socket');

    req.session.destroy(function (err){
        if(err) {
            console.error("userLogout failed with error:", err);
            return next(err);
        }
        else {
            console.log("this_socket:", this_socket);
            console.log("io:", io);
            this_socket.sockets.in(sessionID).emit('userAction', { action: 'logout' });
            //other logic to remove old sessions from DB Session Store
            //and finally:
            res.status(200)
                .json({
                status: 'success',
                api_data: {'loggedIn':false},
                message: 'Logout successful.'
                });
        }
    }
}
exports.userLogout = function(req, res, next) {
    const sessionID = req.session.id;
    const userId = MAGIC_GET_USER_ID_FROM_SESSION_ID(sessionID) // who want to logout
    const io = req.app.get('socketio');
    const this_socket = req.app.get(userId); // get "user socket"

    req.session.destroy(function (err){
        if(err) {
            console.error("userLogout failed with error:", err);
            return next(err);
        }
        else {
            console.log("this_socket:", this_socket);
            console.log("io:", io);
            this_socket.emit('userAction', { action: 'logout' });
            //other logic to remove old sessions from DB Session Store
            //and finally:
            res.status(200)
                .json({
                status: 'success',
                api_data: {'loggedIn':false},
                message: 'Logout successful.'
                });
        }
    }
}
我甚至试过这样做:

io.emit('userAction', { action: 'logout' });

但事实证明,它仍然会向所有客户机发出信号。我很确定某个地方存在不匹配,只是不知道在哪里。

如果要向spesific用户发送emit,您需要为每个会话id创建空间

io.on('connection', function (socket) {
  app.set('current_socket', socket);
  var sessionId = socker.request.session.id
  //join room
  socket.join(sessionId);
});
userController.js:

exports.userLogout = function(req, res, next) {
    const sessionID = req.session.id;
    const io = req.app.get('socketio');
    const this_socket = req.app.get('current_socket');

    req.session.destroy(function (err){
        if(err) {
            console.error("userLogout failed with error:", err);
            return next(err);
        }
        else {
            console.log("this_socket:", this_socket);
            console.log("io:", io);
            this_socket.emit('userAction', { action: 'logout' });
            //other logic to remove old sessions from DB Session Store
            //and finally:
            res.status(200)
                .json({
                status: 'success',
                api_data: {'loggedIn':false},
                message: 'Logout successful.'
                });
        }
    }
}
exports.userLogout = function(req, res, next) {
    const sessionID = req.session.id;
    const io = req.app.get('socketio');
    const this_socket = req.app.get('current_socket');

    req.session.destroy(function (err){
        if(err) {
            console.error("userLogout failed with error:", err);
            return next(err);
        }
        else {
            console.log("this_socket:", this_socket);
            console.log("io:", io);
            this_socket.sockets.in(sessionID).emit('userAction', { action: 'logout' });
            //other logic to remove old sessions from DB Session Store
            //and finally:
            res.status(200)
                .json({
                status: 'success',
                api_data: {'loggedIn':false},
                message: 'Logout successful.'
                });
        }
    }
}
exports.userLogout = function(req, res, next) {
    const sessionID = req.session.id;
    const userId = MAGIC_GET_USER_ID_FROM_SESSION_ID(sessionID) // who want to logout
    const io = req.app.get('socketio');
    const this_socket = req.app.get(userId); // get "user socket"

    req.session.destroy(function (err){
        if(err) {
            console.error("userLogout failed with error:", err);
            return next(err);
        }
        else {
            console.log("this_socket:", this_socket);
            console.log("io:", io);
            this_socket.emit('userAction', { action: 'logout' });
            //other logic to remove old sessions from DB Session Store
            //and finally:
            res.status(200)
                .json({
                status: 'success',
                api_data: {'loggedIn':false},
                message: 'Logout successful.'
                });
        }
    }
}

必须为每个用户定义唯一的套接字对象。我们有很多方法可以做到这一点

简单地说,我们使用用户id(unique)作为存储套接字对象的键(映射方式:key(userId)-vaule(socketObj))

跟着兔子走:

当用户登录时,客户端向服务器端发出一个事件(登录),该事件包括用户id

客户端:

// login success
socket.emit('userLoggedIn', {userId: THE_USER_ID})
服务器端:

io.on('connection', function (socket) {
  // app.set('current_socket', socket);
  console.log('No of clients:', io.engine.clientsCount);
  socket.on('userLoggedIn', function(data) => {
    app.set(data.userId, socket); // save socket object
  })
});
userController.js:

exports.userLogout = function(req, res, next) {
    const sessionID = req.session.id;
    const io = req.app.get('socketio');
    const this_socket = req.app.get('current_socket');

    req.session.destroy(function (err){
        if(err) {
            console.error("userLogout failed with error:", err);
            return next(err);
        }
        else {
            console.log("this_socket:", this_socket);
            console.log("io:", io);
            this_socket.emit('userAction', { action: 'logout' });
            //other logic to remove old sessions from DB Session Store
            //and finally:
            res.status(200)
                .json({
                status: 'success',
                api_data: {'loggedIn':false},
                message: 'Logout successful.'
                });
        }
    }
}
exports.userLogout = function(req, res, next) {
    const sessionID = req.session.id;
    const io = req.app.get('socketio');
    const this_socket = req.app.get('current_socket');

    req.session.destroy(function (err){
        if(err) {
            console.error("userLogout failed with error:", err);
            return next(err);
        }
        else {
            console.log("this_socket:", this_socket);
            console.log("io:", io);
            this_socket.sockets.in(sessionID).emit('userAction', { action: 'logout' });
            //other logic to remove old sessions from DB Session Store
            //and finally:
            res.status(200)
                .json({
                status: 'success',
                api_data: {'loggedIn':false},
                message: 'Logout successful.'
                });
        }
    }
}
exports.userLogout = function(req, res, next) {
    const sessionID = req.session.id;
    const userId = MAGIC_GET_USER_ID_FROM_SESSION_ID(sessionID) // who want to logout
    const io = req.app.get('socketio');
    const this_socket = req.app.get(userId); // get "user socket"

    req.session.destroy(function (err){
        if(err) {
            console.error("userLogout failed with error:", err);
            return next(err);
        }
        else {
            console.log("this_socket:", this_socket);
            console.log("io:", io);
            this_socket.emit('userAction', { action: 'logout' });
            //other logic to remove old sessions from DB Session Store
            //and finally:
            res.status(200)
                .json({
                status: 'success',
                api_data: {'loggedIn':false},
                message: 'Logout successful.'
                });
        }
    }
}

socket.request.session.id未定义。嗯。@jfriend00你能给我一个详细的例子吗?你在给你的服务器编码,就像一次只有一个用户使用你的服务器一样。您不能将
当前\u套接字
存储在全球可用的位置。由于不同的用户在您的服务器上执行不同的操作,这些操作将发生冲突。相反,您需要将用户状态存储在用户会话中或直接存储在cookie中,然后当该特定用户发生请求时,您可以从该用户的会话或cookie中获取状态。嘿!非常感谢你的建议。我确实意识到我的设置对流量不友好,因此我需要帮助使其对大量用户稳定。我不熟悉节点和套接字。无论如何,我确实尝试过实现您的解决方案,但不知怎么的,“userLoggedIn”并没有被激发,尽管如此(这很奇怪),“userAction”正在被激发,我在所有客户端上都收到了一条注销消息。pm2/节点是否存在捕获问题?