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

Next.js 13.4 App Router下Socket.IO服务端TS适配求助

适配Next.js 13.4 App Router的Socket.IO TypeScript实现方案

1. 安装依赖

确保安装最新版Socket.IO及TypeScript类型定义:

npm install socket.io socket.io-client @types/socket.io @types/socket.io-client

2. 搭建Socket.IO服务器(适配App Router)

App Router的Route Handler是无状态的,无法直接沿用传统HTTP服务器写法,需通过单例模式初始化Socket.IO服务,并在Route Handler中桥接WebSocket连接:

步骤1:创建Socket.IO服务实例文件

新建app/api/socket/io.ts:

import { Server } from 'socket.io';

// 单例存储Socket.IO服务器实例
let io: Server | null = null;

export function initSocketIO(server: any) {
  if (!io) {
    io = new Server(server, {
      path: '/api/socket/io',
      cors: {
        origin: process.env.NEXT_PUBLIC_APP_URL || 'http://localhost:3000',
        methods: ['GET', 'POST'],
      },
    });

    // 定义Socket.IO事件逻辑
    io.on('connection', (socket) => {
      console.log('用户已连接:', socket.id);

      socket.on('send-message', (data) => {
        console.log('收到客户端消息:', data);
        socket.emit('receive-message', `服务器响应:${data}`);
      });

      socket.on('disconnect', () => {
        console.log('用户已断开连接:', socket.id);
      });
    });
  }
  return io;
}

export function getSocketIO() {
  if (!io) {
    throw new Error('Socket.IO服务器未完成初始化');
  }
  return io;
}

步骤2:创建App Router的Route Handler

新建app/api/socket/route.ts,利用Next.js的WebSocket API处理连接:

import { NextResponse } from 'next/server';
import { initSocketIO } from './io';

export async function POST(request: Request) {
  const { socket, response } = NextResponse.webSocket();

  // 初始化Socket.IO服务
  const io = initSocketIO(response.socket.server);

  // 桥接客户端WebSocket消息到Socket.IO
  socket.on('message', (data) => {
    io.emit('receive-message', data);
  });

  return response;
}

// 处理CORS预检请求
export async function OPTIONS() {
  return new NextResponse(null, {
    status: 200,
    headers: {
      'Access-Control-Allow-Origin': '*',
      'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',
      'Access-Control-Allow-Headers': 'Content-Type',
    },
  });
}

3. 客户端组件实现(client.tsx)

确保组件开启客户端模式,连接到Socket.IO服务:

'use client';

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

export default function SocketClient() {
  const [inputMessage, setInputMessage] = useState('');
  const [serverMessage, setServerMessage] = useState('');
  let socket: Socket | null = null;

  useEffect(() => {
    // 初始化Socket.IO客户端
    socket = io('/api/socket/io', {
      transports: ['websocket'],
    });

    // 监听服务器消息
    socket.on('receive-message', (data) => {
      setServerMessage(data);
    });

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

  const sendMessage = () => {
    if (socket && inputMessage) {
      socket.emit('send-message', inputMessage);
      setInputMessage('');
    }
  };

  return (
    <div className="p-4">
      <input
        type="text"
        value={inputMessage}
        onChange={(e) => setInputMessage(e.target.value)}
        placeholder="输入消息发送给服务器"
        className="border p-2 mr-2"
      />
      <button onClick={sendMessage} className="bg-blue-500 text-white p-2 rounded">
        发送
      </button>
      {serverMessage && <p className="mt-4">服务器回复:{serverMessage}</p>}
    </div>
  );
}

4. 关键注意事项

  • 单例服务:通过initSocketIO确保Socket.IO服务器仅初始化一次,避免重复创建实例
  • CORS配置:根据实际生产环境调整cors.origin,避免跨域错误
  • WebSocket传输:客户端指定transports: ['websocket'],优先使用WebSocket协议而非轮询
  • Route Handler兼容性:仅Next.js 13.4+支持NextResponse.webSocket(),确保版本匹配

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 05:42:44