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

Next.js 13.2+路由处理器中如何构建WebSocket?

在Next.js 13.2+中构建WebSocket的解决方案

Next.js 13.2+的App Router路由处理器(app目录下的route.js)基于Fetch API规范,无法直接处理WebSocket所需的HTTP Upgrade请求,这就是你在GET处理器中尝试使用WebSocket失败的原因,且目前官方文档确实未提供App Router内直接支持WebSocket的方案。

以下是两种可行的实现方式:

方案一:使用Pages Router的API路由

Pages Router的API路由基于Node.js HTTP服务器,可以直接处理WebSocket连接升级:

  1. 首先安装WebSocket库(以ws为例):
npm install ws
  1. 在pages/api/ws.js中创建WebSocket处理逻辑:
import { WebSocketServer } from 'ws';

export default function handler(req, res) {
  // 检查是否为WebSocket升级请求
  if (req.method === 'GET' && req.headers.upgrade === 'websocket') {
    const wss = new WebSocketServer({ noServer: true });

    // 升级HTTP连接到WebSocket协议
    wss.handleUpgrade(req, req.socket, Buffer.alloc(0), (ws) => {
      wss.emit('connection', ws, req);
    });

    // 处理客户端连接
    wss.on('connection', (ws) => {
      console.log('Client connected');

      // 接收客户端消息并返回响应
      ws.on('message', (data) => {
        const message = data.toString();
        console.log(`Received: ${message}`);
        ws.send(`Server response: ${message}`);
      });

      // 处理客户端断开连接
      ws.on('close', () => {
        console.log('Client disconnected');
      });
    });

    // 确保连接关闭时清理资源
    res.socket.on('close', () => {
      wss.close();
    });
  } else {
    res.status(404).send('WebSocket endpoint only');
  }
}

// 禁用Next.js默认的请求解析和处理
export const config = {
  api: {
    bodyParser: false,
    externalResolver: true,
  },
};
  1. 前端页面中连接WebSocket:
// 示例:在客户端组件中连接
'use client';

import { useEffect } from 'react';

export default function WebSocketClient() {
  useEffect(() => {
    const ws = new WebSocket(`ws://${window.location.host}/api/ws`);

    ws.onopen = () => {
      ws.send('Hello from client!');
    };

    ws.onmessage = (event) => {
      console.log('Server message:', event.data);
    };

    ws.onclose = () => {
      console.log('Disconnected from server');
    };

    // 组件卸载时关闭连接
    return () => {
      ws.close();
    };
  }, []);

  return <div>WebSocket client running</div>;
}

方案二:使用自定义服务器(完全控制HTTP服务器)

如果你需要对服务器有完全控制权,可以搭建自定义Express/Node.js服务器并集成WebSocket:

  1. 安装依赖:
npm install express ws next
  1. 创建根目录下的server.js:
const express = require('express');
const next = require('next');
const { createServer } = require('http');
const { WebSocketServer } = require('ws');

const dev = process.env.NODE_ENV !== 'production';
const app = next({ dev });
const handle = app.getRequestHandler();

app.prepare().then(() => {
  const expressApp = express();
  const httpServer = createServer(expressApp);
  const wss = new WebSocketServer({ server: httpServer });

  // 处理WebSocket连接
  wss.on('connection', (ws) => {
    ws.on('message', (data) => {
      console.log(`Received message: ${data.toString()}`);
      ws.send(`Echo: ${data.toString()}`);
    });
  });

  // 让Next.js处理所有其他路由
  expressApp.all('*', (req, res) => {
    return handle(req, res);
  });

  httpServer.listen(3000, () => {
    console.log('Server running on http://localhost:3000');
  });
});
  1. 修改package.json的启动脚本:
{
  "scripts": {
    "dev": "node server.js",
    "build": "next build",
    "start": "NODE_ENV=production node server.js"
  }
}

注意事项

  • App Router路由处理器目前不支持WebSocket,这是由其基于Fetch API的设计限制决定的,后续官方可能会推出相关支持,但当前阶段只能通过上述两种方案实现。
  • 如果使用Vercel部署,Pages Router的WebSocket API路由需要使用Serverless Functions,而自定义服务器则需要部署到支持Node.js服务器的平台(如Vercel的Edge Functions不支持WebSocket,需用Serverless或自定义部署)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 04:15:33