You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

新版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.js http.Server实例,正好满足ws库的要求。
  • express-session集成:在WebSocket的upgrade事件中,我们先用express-session中间件处理请求,解析出会话后再升级到WebSocket连接,这样就能在WebSocket连接中访问用户会话数据。
  • 资源清理:添加了服务器关闭时的资源清理逻辑,避免内存泄漏。

内容的提问来源于stack exchange,提问作者PirateApp

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 17:27:28