Не удается отправить конкретному клиенту: Socket IO отправляет его каждому клиенту? - PullRequest
0 голосов
/ 06 января 2019

Да, я просмотрел документацию, которая очень хорошо написана: Socket IO Cheatsheet

Вот проблема: я хочу уведомить пользователя о выходе из системы, когда его сеанс из Express App разрушается. Вот что происходит: когда я выхожу из сеанса, все другие клиенты (включая тех, кто уже вошел или даже не вошел в систему) получают сообщение о том, что они вышли из системы. Да, мое экспресс-приложение работает нормально - они не выходят из системы, но я верю, что 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.'
                });
        }
    }
}

Я даже попробовал это вместо:

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

но оказывается, что он все еще излучает всем клиентам. Я почти уверен, что где-то есть несоответствие, просто не могу понять, где.

Ответы [ 2 ]

0 голосов
/ 07 января 2019

Вы должны определить уникальный объект сокета для каждого пользователя. У нас есть много способов сделать это.

Проще говоря, мы используем идентификатор пользователя (уникальный) в качестве ключа для хранения объекта сокета (путь карты: ключ (userId) - vaule (socketObj)).

Следуй за кроликом:

Когда пользователь входит в систему, клиентская сторона отправляет событие (логин) на серверную часть, событие включает в себя идентификатор пользователя.

Клиентская сторона:

// 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 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.'
                });
        }
    }
}
0 голосов
/ 06 января 2019

Вам нужно создать место для каждого идентификатора сеанса, если вы хотите отправить сообщения специальному пользователю

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.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.'
                });
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...