我试图从使用Express.js框架的Node.js服务器触发的'升级'事件访问会话对象。我已经正确设置了Session支持,并且可以从标准的。get .post .put和。delete方法访问它,例如
app.get('/', function(req, res) {
req.session.test = 'Hello world'; // Works fine
res.render('index');
});
但是如果我像这样在服务器上连接一个on 'upgrade'事件:
app.on('upgrade', function(req, socket) {
var message = req.session.test; // Doesn't work
});
我无法访问会话对象。据我所知,Connect Session中间件仅为get/post/put/delete方法连接会话,但不为自定义事件(如'upgrade')连接会话。
仅供参考,一个'升级'事件是在WebSocket握手期间从客户端发出的,我试图从初始的WebSocket握手访问会话。会话cookie肯定存在于握手期间的HTTP报头中,例如:
app.on('upgrade', function(req, socket) {
var cookieHeader = req.headers['cookie'];
console.log(cookieHeader);
});
…将输出Connect会话cookie。是否有一种方法可以使用原始会话cookie令牌手动构建会话对象?
更新:一直在谈论一些人在node.js IRC聊天室,显然这是非常困难或不可能的。Connect中间件不暴露于自定义/不寻常事件,如"升级"。他们说要在Github中提出一个问题,所以在这里:
https://github.com/senchalabs/connect/issues/342由于您无法访问响应对象,因此您应该能够通过获取会话存储并使用从cookie获得的session_id调用get(session_id, callback)
来查找会话对象。如果您拥有的req
对象通过req.res
链接到响应,那么您也可以实际调用正常的会话中间件函数,express.js将为您做,但如果这是一个原始的node.js事件,那么此时可能还没有进行连接。在创建中间件时,必须手动创建会话存储实例并保持对它的引用,然后将其传递给options
对象中的会话中间件工厂函数。
如果您正在使用express-session,这应该会有所帮助:
import session from 'express-session'
import express from 'express'
import http from 'http'
import { WebSocketServer } from 'ws'
// Declare an Express app
const app = express()
// Declare an HTTP server for the app
const server = http.createServer(app)
// Initialize *express-session* and use it as a middleware
const sessionHandler = session({
saveUninitialized: false,
secret: 'my little secret',
resave: false
})
app.use(sessionHandler)
// Define a builder for message handler with WebSocket and Session as context
const onMessage = (ws, session) => (message) => {
// create a handler for message given the ws and session
}
// Create a *WebSocketServer* without an attached HTTP server
const wsServer = new WebSocketServer({ noServer: true })
// define what to do on a 'connection' event
wsServer.on('connection', (ws, session) => {
ws.on('message', onMessage(ws, session))
})
// 'upgrade' event comes when the browser ask for a WebSocket
server.on('upgrade', (req, socket, head) => {
// we call the *sessionHandler* to retrieve/create the session
sessionHandler(req, {}, () => {
// ask the *WebSocketServer* to manage the upgrade
wsServer.handleUpgrade(req, socket, head, (ws) => {
console.log(req.session)
// emit a 'connection' event (handler above) with the create WebSocket and current session
wsServer.emit('connection', ws, req.session)
})
})
})