我似乎在让 Express、express-session、connect-redis 和 websockets/ws 很好地协同工作时遇到了一些麻烦。这很可能与我对这些模块和编码的总体理解还有限有关。这里的大部分代码取自存储库中的相应示例以及试图完成类似任务的其他来源。
所以我们这里有一个启用了 websocket 的应用程序,它试图立即启动与服务器端应用程序的 websocket 连接,该应用程序当前除了提供 websocket 功能之外什么也不做。该请求首先到达我们的 NGINX API 代理,该代理将请求代理到本地运行的 Node 应用程序实例。
Node 应用程序应配置为接受并立即升级到 websocket 的请求,创建唯一的 session 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
session ID:eavjOlls59jtjQd-gZ0EIhqf3_P6sYMr
session Cookie: {"originalMaxAge":3600,"expires":"2017-05- 27T13:59:19.663Z","安全":true,"httpOnly":true,"路径":"/"}
Redis 对索引键的响应:
<小时 />通过取消注释相关部分来启用 connect-redis 会导致启动时服务器上出现以下错误消息:
<小时 /> /home/ubuntu/app/njs/nl-websocket-dev/node_modules/connect-redis/lib/connect-redis.js:39 var Store = session.Store; ^类型错误:无法读取未定义的属性“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/stackoverflow.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
<小时 />请注意,我按照自己的方式启动了快速 session ,这样我就可以将其绑定(bind)到 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
,但它并不完整,所以我假设您在某个地方调用 app.use(session)
。