新版Nuxt无server文件夹,如何适配带session的ws库WebSocket代码?
在新版Nuxt(无server文件夹)中集成ws库与express-session
我刚好之前在Nuxt 3里处理过类似的WebSocket集成需求,新版Nuxt基于Nitro引擎,没有了旧版的server文件夹和index.js,但我们可以通过Nitro的生命周期钩子来获取底层的HTTP服务器实例,完美适配你现有的ws代码。下面是具体的实现步骤:
1. 安装依赖
首先安装需要的包:
npm install ws express-session # 如果你用TypeScript,还需要安装类型定义 npm install -D @types/ws @types/express-session
2. 创建Nitro插件
新版Nuxt中,我们需要在server/plugins目录下创建一个Nitro插件(目录不存在可手动创建),比如命名为websocket.js,用来挂载WebSocket服务:
const WebSocket = require('ws'); const session = require('express-session'); const { useLogger } = require('nitropack'); // 复用你原有的WebSocket逻辑,适配Nuxt环境 function websocket({ server, sessionHandler }) { const logger = useLogger('websocket'); const wss = new WebSocket.Server({ noServer: true }); function noop() {} function heartbeat() { this.isAlive = true; } wss.on('connection', (ws, request) => { ws.isAlive = true; ws.on('pong', heartbeat); ws.on('message', (msg) => { logger.info(`Received message ${msg}`); // 这里可以通过request.session获取用户会话数据 logger.info(`User session data: ${JSON.stringify(request.session)}`); ws.send('Message received successfully'); }); }); server.on('upgrade', (request, socket, head) => { // 用express-session处理请求会话 sessionHandler(request, {}, () => { logger.info(`WebSocket session parsed: ${JSON.stringify(request.session)}`); wss.handleUpgrade(request, socket, head, (ws) => { wss.emit('connection', ws, request); }); }); }); // 心跳检测定时器,服务器关闭时清理 const pingInterval = setInterval(() => { wss.clients.forEach((ws) => { if (ws.isAlive === false) return ws.terminate(); ws.isAlive = false; ws.ping(noop); }); }, 30000); // 监听服务器关闭事件,清理资源 server.on('close', () => { clearInterval(pingInterval); wss.close(); logger.info('WebSocket server closed'); }); return wss; } // 导出Nitro插件 export default defineNitroPlugin((nitroApp) => { // 配置express-session const sessionHandler = session({ secret: process.env.SESSION_SECRET || 'your-strong-secret-key-here', resave: false, saveUninitialized: false, cookie: { secure: process.env.NODE_ENV === 'production', // 生产环境开启HTTPS-only httpOnly: true, maxAge: 24 * 60 * 60 * 1000 // 会话有效期1天 } }); // 当Nitro启动HTTP服务器后触发钩子 nitroApp.hooks.hook('listen', (server) => { logger.info('Starting WebSocket server...'); websocket({ server, sessionHandler }); }); });
3. 配置会话密钥(重要)
在项目根目录创建.env文件,设置安全的会话密钥(生产环境绝对不要硬编码!):
SESSION_SECRET=your-super-strong-secret-key-change-in-production
4. 启动Nuxt
现在你可以正常启动Nuxt了:
# 开发模式 npm run dev # 生产构建 npm run build && npm run preview
关键说明
- Nitro的
listen钩子:这个钩子会在Nuxt的底层HTTP服务器启动后触发,此时我们能拿到原生的Node.jshttp.Server实例,正好满足ws库的要求。 - express-session集成:在WebSocket的
upgrade事件中,我们先用express-session中间件处理请求,解析出会话后再升级到WebSocket连接,这样就能在WebSocket连接中访问用户会话数据。 - 资源清理:添加了服务器关闭时的资源清理逻辑,避免内存泄漏。
内容的提问来源于stack exchange,提问作者PirateApp
相关产品推荐
相关产品推荐

