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

Next.js 13.2.3 Beta:如何为NextResponse添加Server属性集成Socket.io?

Next.js App Router(新路由API)集成Socket.io方案

问题背景

之前在Next.js Pages Router中,通过扩展NextApiResponse类型并在API路由中初始化Socket.io的方式可以正常工作,但切换到App Router的新API路由模式(导出GET/POST方法、使用NextResponse返回结果)后,无法直接获取到底层的http.Server对象,尝试扩展NextResponse类型也无法解决实际的集成问题。

解决方案:自定义Next.js服务器集成Socket.io

App Router的API路由基于Web标准的Request/Response接口,没有直接暴露底层HTTP服务器实例,因此更可靠的方式是自定义Next.js服务器,直接在HTTP服务器上挂载Socket.io。

步骤1:创建自定义服务器文件

在项目根目录创建server.ts(或server.js):

import { createServer } from 'http';
import { parse } from 'url';
import next from 'next';
import { Server as SocketIOServer } from 'socket.io';

const dev = process.env.NODE_ENV !== 'production';
const hostname = 'localhost';
const port = 3000;

// 初始化Next.js应用
const app = next({ dev, hostname, port });
const handle = app.getRequestHandler();

app.prepare().then(() => {
  // 创建HTTP服务器
  const server = createServer(async (req, res) => {
    try {
      const parsedUrl = parse(req.url!, true);
      // 让Next.js处理所有请求
      await handle(req, res, parsedUrl);
    } catch (err) {
      console.error('处理请求出错:', req.url, err);
      res.statusCode = 500;
      res.end('Internal Server Error');
    }
  });

  // 初始化Socket.io并挂载到HTTP服务器
  const io = new SocketIOServer(server, {
    cors: {
      origin: "http://localhost:3000", // 根据你的前端地址调整
      methods: ["GET", "POST"]
    }
  });

  // 定义Socket.io事件逻辑
  io.on('connection', (socket) => {
    console.log('新客户端已连接');
    
    socket.on('disconnect', () => {
      console.log('客户端已断开连接');
    });

    socket.on('remoteControl', (event: any) => {
      io.emit('remoteControl', event); // 广播事件给所有客户端
    });
  });

  // 启动服务器
  server.listen(port, () => {
    console.log(`> 服务已启动:http://${hostname}:${port}`);
  });
});

步骤2:修改启动命令

更新package.json中的scripts,使用自定义服务器启动项目:

{
  "scripts": {
    "dev": "ts-node server.ts",
    "build": "next build",
    "start": "NODE_ENV=production ts-node server.ts"
  }
}

注意:如果使用JavaScript而非TypeScript,将ts-node替换为node即可。

步骤3:客户端连接Socket.io

在客户端组件(需标记为'use client')中连接Socket.io:

'use client';

import { useEffect } from 'react';
import { io, Socket } from 'socket.io-client';

export default function SocketClient() {
  useEffect(() => {
    // 连接到Socket.io服务器
    const socket: Socket = io('http://localhost:3000');

    socket.on('connect', () => {
      console.log('已连接到Socket.io服务器');
    });

    // 监听服务器推送的事件
    socket.on('remoteControl', (event) => {
      console.log('收到remoteControl事件:', event);
    });

    // 示例:发送事件到服务器
    socket.emit('remoteControl', { action: 'volumeUp' });

    // 组件卸载时断开连接
    return () => {
      socket.disconnect();
    };
  }, []);

  return null;
}

关键说明

  • App Router的API路由设计为无状态、可部署到Edge环境,因此不适合直接在API路由中挂载Socket.io这类需要长期持有连接的服务。
  • 自定义服务器方式可以完全控制底层HTTP服务器,确保Socket.io的连接稳定性,同时保留Next.js的所有功能。
  • 不需要扩展NextResponse类型,Socket.io直接与HTTP服务器绑定,客户端通过地址直接连接即可。

内容的提问来源于stack exchange,提问作者Juan Carlos Campbell

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 12:17:23