express-session,connect-redis和einaros / ws

时间:2017-05-27 15:20:16

标签: node.js express websocket node-redis express-session

我似乎在使Express,express-session,connect-redis和websockets / ws很好地一起玩时遇到了一些麻烦。这很可能与我对这些模块和编码的有限理解有关。这里的大多数代码都来自存储库中的相应示例以及其他尝试完成类似操作的源代码。

所以我们这里有一个支持websocket的应用程序试图立即启动到服务器端应用程序的websocket连接,它除了提供当前的websocket功能外什么都不做。此请求首先命中我们的NGINX API代理,该代理将请求代理到本地运行的Node应用程序实例。

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

以下代码WITHOUT 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""安全":真,"仅Http":真,"路径":" /" }

Redis响应索引键:

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

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

TypeError:无法读取属性' Store'未定义的     at 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/stackoverflow.js:8:48)     在Module._compile(module.js:409:26)     at 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

请注意,我按照我的方式启动了快速会话,因此我可以将其绑定到websockets / ws。我已经尝试了很多配置,这实际上是唯一允许express-session和websockets / ws一起工作的配置。我从“阿兹米索夫”中得到了一个要点。这里(特别是不包括connect-redis):

ExpressJS & Websocket & session sharing

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

欢迎任何关于如何使这项工作的想法。

1 个答案:

答案 0 :(得分:0)

您在此处使用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的任何位置,但它不完整,所以我假设您在某处“{1}}重新打电话给app.use(session)