express-session、connect-redis 和 einaros/ws

express-session, connect-redis and einaros/ws

我似乎在让 Express、express-session、connect-redis 和 websockets/ws 很好地协同工作时遇到了一些麻烦。这很可能与我对这些模块和一般编码的理解有限有关。这里的大部分代码取自存储库中的相应示例以及试图完成类似事情的其他来源。

所以我们这里有一个支持 websocket 的应用程序,它试图立即启动到服务器端应用程序的 websocket 连接,该应用程序目前只提供 websocket 功能。该请求首先到达我们的 NGINX API 代理,该代理将请求代理到 Node 应用程序的本地 运行 实例。

Node 应用程序应配置为接受并立即将请求升级到 websocket,创建唯一的会话 ID 和 cookie,然后将其存储在我们的 Redis 框中。除了 Redis 中的存储之外,所有这些都正常运行。

以下代码无需 connect-redis 即可工作(我直接使用 node_redis 客户端来查询 Redis 框的任何键):

'use strict';

const express = require('express');
const http = require('http');
const ws = require('ws');
const redis = require('redis');
const client = redis.createClient(6379, '10.0.130.10', {no_ready_check: true});
//const RedisStore = require('connect-redis')(session);


var session = require('express-session')({
    //store: new RedisStore({host: '10.0.130.10', port: '6379', ttl: 60, logErrors: true}),
    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 });


// Client heartbeat
function heartbeat() {
    this.isAlive = true;
}


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

    // Obtain Client IP address from NGINX x-forwarded-for proxy header
    let clientIp = req.headers['x-forwarded-for'];

请求后的服务器输出:


收听:10031

会话 ID:eavjOlls59jtjQd-gZ0EIhqf3_P6sYMr

会话 Cookie:{"originalMaxAge":3600,"expires":"2017-05- 27T13:59:19.663Z","secure":true,"httpOnly":true,"path":"/"}

Redis 对索引键的响应:


通过取消注释相关部分来启用 connect-redis 会在启动时在服务器上显示以下错误消息:


/home/ubuntu/app/njs/nl-websocket-dev/node_modules/connect-redis/lib/connect-redis.js:39 变量存储= session.Store; ^

TypeError: 无法读取未定义的 属性 'Store' 在 module.exports (/home/ubuntu/app/njs/nl-websocket-dev/node_modules/connect-redis/lib/connect-redis.js:39:22) 在对象。 (/home/ubuntu/app/njs/nl-websocket-dev/Whosebug.js:8:48) 在 Module._compile (module.js:409:26) 在 Object.Module._extensions..js (module.js:416:10) 在 Module.load (module.js:343:32) 在 Function.Module._load (module.js:300:12) 在 Function.Module.runMain (module.js:441:10) 启动时 (node.js:139:18) 在 node.js:968:3


请注意,我以我的方式启动了 express-session,因此我可以将其绑定到 websockets/ws。我已经尝试了很多配置,这实际上是唯一允许 express-session 和 websockets/ws 一起工作的配置。我从 'Azmisov' 这里得到了要点(特别不包括 connect-redis):

ExpressJS & Websocket & session sharing

以这种方式将 express-session 调用到 websockets/ws 确实有效。但是,将 connect-redis 添加到 express-session 上,然后在 websockets/ws 中调用该组合是问题开始的地方,使用此配置。

欢迎提出有关如何实现此功能的任何想法。

您在这里使用 session

const RedisStore = require('connect-redis')(session);

稍后在此处定义:

var session = require('express-session')(...);

所以这是第一个问题(session 未定义)。

另一个问题是 connect-redis 应该传递 require('express-session') 的结果,而您的代码试图传递它的实例化版本。

这两个问题都可以这样解决:

const Session    = require('express-session');
const RedisStore = require('connect-redis')(Session);

var session = Session({
  store: new RedisStore(...),
  ...
});

我也没有看到 session 如何附加到 app 您 post 代码中的任何地方,但它不完整,所以我假设您正在调用的某个地方app.use(session).