Вызов экспресс-сеанса при поддержке connect-redis внутри websockets/ws

Хорошо, так вот. Я пытаюсь использовать express-session при поддержке connect-redis вместе с websockets/ws. Подавляющее большинство примеров кода, которые я видел, обычно включают использование Express для обслуживания клиента сценария веб-сокета определенного типа, а затем настройку серверного приложения для использования промежуточного программного обеспечения express-session для работы с данными сеанса... с веб-сокетами дальше по процессу. цепь.

Мое приложение на стороне клиента, с другой стороны, немедленно инициирует запрос открытия/обновления, который обходит Express и направляется прямо в websockets/ws. По этой причине я не могу работать с данными сеанса с помощью широко используемой установки промежуточного программного обеспечения app.use(session(...).

В приведенном ниже коде используется настройка, которая позволяет мне вызывать express-session внутри websocket/ws и передавать запрос на соединение через express-session, чтобы я мог получить данные сеанса. Это работает, как показано на выходе также ниже. Однако не работает поддержка express-session на connect-redis внутри этой установки. Чтобы проверить, я вызываю клиент Redis напрямую, чтобы запросить мой ящик Redis после запуска express-session, ключи не возвращаются.

У меня есть три вопроса: 1. Является ли то, что я делаю ниже, «правильным» способом интеграции express-session с websockets/ws для описанной установки клиента? 2. Если нет, что мне делать? 3. Если это хороший способ, можно ли заставить connect-redis работать как хранилище сеансов?

Ваши идеи очень приветствуются.

Серверный код:

const express = require('express');
const Session = require('express-session');
const http = require('http');
const ws = require('ws');
const util = require('util');
const redis = require('redis');
const client = redis.createClient(6379, '10.0.130.10', {no_ready_check: true});
const RedisStore = require('connect-redis')(Session);
const SessionStore = new RedisStore({host: '10.0.130.10', port: '6379', ttl: 60, logErrors: true});
//const SessionStore = new Session.MemoryStore();


var session = Session({
    store: SessionStore,
    cookie: {secure: true, maxAge: 3600, httpOnly: true},
    resave: false,
    saveUninitialized: true,
    secret: '12345'
});


// Define Express and WS servers
const app = express();
const server = http.createServer(app);
const wss = new ws.Server({ server });


// WS Websocket
wss.on('connection', function connection(ws, req) {

    session(req, {}, function(){
        let sessionId = req.sessionID;
        console.log('SessionID: ' + sessionId);

        let sessionCookie = req.session.cookie;
        console.log('SessionCookie: ' + JSON.stringify(sessionCookie));
    });

    client.keys('*', function(err, reply) {
        // reply is null when the key is missing
        console.log('Redis reponse: ' + reply);
    });
});


server.listen(10031, function listening() {
  console.log('Listening on: ' + server.address().port);
});

Вывод console.log на стороне сервера (обратите внимание на ответ Redis):

Listening on: 10031 SessionID: Oi8AdsoZTAm3hRLmxPfGo43Kmmj_Yd6F SessionCookie: {"originalMaxAge":3599,"expires":"2017-05-29T17:45:54.467Z","secure":true,"httpOnly":true,"path":"/"} Redis reponse:

Ссылка: express-session, connect-redis и einaros/ws Ссылка : ExpressJS, Websocket и совместное использование сеансов


person rhamstra    schedule 29.05.2017    source источник
comment
Совместное использование сеанса предполагает, что вы хотите, чтобы Express и обработчики Websocket совместно использовали объект сеанса. Однако ваше приложение Express, похоже, ничего не делает, так в чем же смысл общего сеанса в этой ситуации?   -  person robertklep    schedule 29.05.2017
comment
@robertklep на данный момент я хочу иметь возможность отслеживать пользователей (добавляя также другие идентификаторы пользователей при подключении к системе и централизованно хранить данные отслеживания, чтобы к ним можно было получить доступ с других устройств / служб в нашей среде). Я предполагаю, что в какой-то момент мы начнем взаимодействовать с Express и включим аутентификацию.   -  person rhamstra    schedule 29.05.2017
comment
Внутри обратного вызова, который вы передаете session, попробуйте явно вызвать req.session.save() и из < i>это обратный вызов, вызовите client.keys('*', ...).   -  person robertklep    schedule 30.05.2017
comment
Да, это работает отлично! Теперь я могу использовать SessionStore.get(sessionId, function (error, session){...}); для получения данных, относящихся к текущему сеансу, из Store. Еще раз спасибо за вашу помощь, сэр, очень признателен!   -  person rhamstra    schedule 30.05.2017
comment
Мне интересно, является ли сеанс липким, потому что, как я вижу, промежуточное программное обеспечение сеанса никак не может фактически установить файл cookie сеанса. Если вы перезагрузитесь, я предполагаю, что вы будете получать новый идентификатор сеанса каждый раз (также, чтобы предотвратить ложные срабатывания, перед тестированием убедитесь, что в вашем браузере нет существующих файлов cookie сеанса).   -  person robertklep    schedule 30.05.2017
comment
Действительно, в настоящее время сеанс не является «липким», перезагрузка браузера приводит к истечению срока действия старого веб-сокета после истечения времени ожидания, а новый веб-сокет получает новый идентификатор сеанса. Тем не менее, я видел несколько примеров установки файла cookie при первоначальном запросе на обновление websockets. Однако это не сработает в этой настройке, поскольку в этот момент express-session еще не используется, чтобы фактически предоставить идентификатор сеанса для файла cookie?   -  person rhamstra    schedule 30.05.2017
comment
Это правильно. Сначала я смотрел на событие headers. который выдает сервер WS, и где вы можете установить дополнительные заголовки (например, файл cookie сеанса), но он выглядит синхронным, поэтому вы не можете запустить session(req, {}, ...), чтобы express-session сгенерировал новый сеанс, для которого вы можете добавить заголовок файла cookie. В общем, похоже, что вы не сможете легко использовать express-session.   -  person robertklep    schedule 30.05.2017
comment
Проблем предостаточно. К счастью для меня на данный момент, хотя и с ограниченными функциями, его все же можно использовать. Если вы не возражаете, я спрошу, как вы пришли к выводу, что событие headers является синхронным?   -  person rhamstra    schedule 30.05.2017
comment
Потому что он не обеспечивает обратный вызов для вызова после установки заголовков.   -  person robertklep    schedule 30.05.2017