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
相关产品推荐
相关产品推荐

