Как обнаружить несколько соединений socket.io от одного пользователя
Я следил за этим руководством: http://www.danielbaulig.de/socket-ioexpress/, чтобы связать express.js с socket.io, и он работает блестяще.
У меня есть пользователь, входящий в систему на одной странице (express.js POST-запрос, который устанавливает объект сеанса), и когда они аутентифицировали его, он направляет их на новую страницу, где socket.io загружается, а на сервере socket.io может захватывать сеанс, который был установлен из выражения. Так что все работает нормально.
Теперь у меня есть пользователи на странице, которая использует socket.io, и когда эта страница обновляется - иногда соединение socket.io все еще существует (то есть оно не отключается). То, что я пытаюсь сделать, это изменить функцию io.set('authorization')
, чтобы гарантировать, что когда пользователь подключится - он отключит все существующие экземпляры socket.io, которые все еще открыты для этого клиента.
Вот как это выглядит на данный момент:
//socket.io connect to express
var parseCookie = require('connect').utils.parseCookie;
io.set('authorization', function (data, accept) {
if (data.headers.cookie)
{
data.cookie = parseCookie(data.headers.cookie);
data.sessionID = data.cookie['express.sid'];
// (literally) get the session data from the session store
sessionStore.get(data.sessionID, function (err, session)
{
if (err || !session)
{
// if we cannot grab a session, turn down the connection
//note: a session is created when the user logs in
accept('Error', false);
}
else
{
//TODO something here before we accept the connection
//??
// save the session data
data.session = session;
//accept the connection
accept(null, true);
}
});
}
else
{
return accept('No cookie transmitted.', false);
}
});
Как проверить, имеет ли клиент, который должен быть принят, предыдущее соединение, и он все еще открыт (и поэтому нам нужно отключить этот старый).
В экспресс-сеансе есть "имя пользователя", поэтому мы можем получить объект сеанса и получить имя пользователя, я просто не могу понять, как пройти через список всех клиентов socket.io и посмотреть в экспресс-сессии для каждого из них и проверить, совпадает ли он с аутентификацией пользователя в настоящее время.
Ответы
Ответ 1
В моем приложении я явно управляю сеансами socket.io. На стороне сервера, когда будет установлено новое соединение, я делаю что-то вроде: socketio_session[user_id].push(session)
. Это дает мне доступ ко всем сеансам, подключенным для определенного пользователя. В вашем случае вам может не потребоваться хранить список сеансов для каждого пользователя, но только сохранить последний сеанс и onconnect
принудительно отключить связь в существующем сеансе, если он есть, перед сохранением нового сеанса.
Ответ 2
На Socket.IO очень много кода. Старое.
В новой документации (Socket.IO 1.3.6, прямо сейчас) говорится:
"Старые методы io.set() и io.get() устарели и поддерживаются только для обратной совместимости. Вот пример перевода старого стиля в промежуточное программное обеспечение". в разделе "Миграция от 0,9"
Если вы используете новую версию Socket.IO.
Код, который вам нужен, это что-то вроде:
var sessionStore = new MongoStore({ url: config.db });
var cookie = require('cookie-parser')("SECRET");
io.use(function(socket, callback) {
if (socket.request.headers.cookie) {
cookie(socket.request, null, function(err) {
sessionStore.get(socket.request.signedCookies["connect.sid"], function(err, session) {
if (err || !session) {
callback('Session error', false);
} else {
socket.request.sessionID = socket.request.signedCookies["connect.sid"];
console.log(socket.request.sessionID);
callback(null, true);
}
});
});
}
else {
return callback('No session.', false);
}
});
io.on('connection', function(socket) {
console.log(socket.request.sessionID);
});