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

如何从外部React应用连接Next.js的WebSocket服务

解决Next.js Socket.IO服务无法被外部React应用连接的问题

问题根源

  • 你用Next.js搭建的是Socket.IO服务,但外部CRA应用用了原生WebSocket(ws://)连接——Socket.IO是基于WebSocket的封装协议,不能直接用原生WS客户端连接。
  • 出现的404错误,是因为CRA应用没指定Socket.IO服务的正确路径(你的服务路径是/api/socket),默认Socket.IO客户端会请求/socket.io,导致路径不匹配。

解决方案步骤

1. 外部React应用改用Socket.IO客户端

CRA应用里放弃useReactWebSocket,安装并使用socket.io-client:

npm install socket.io-client

修改CRA组件代码:

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

function App() {
  const [socket, setSocket] = useState<Socket | null>(null);
  const [lastMessage, setLastMessage] = useState<string | null>(null);

  useEffect(() => {
    // 连接Next.js的Socket.IO服务,指定正确路径
    const newSocket = io('http://localhost:3000', {
      path: '/api/socket',
      transports: ['websocket'] // 强制用WebSocket传输,避免polling方式的问题
    });

    // 监听连接成功
    newSocket.on('connect', () => {
      console.log('连接到Socket.IO服务');
    });

    // 监听Next.js发送的消息
    newSocket.on('newIncomingMessage', (msg) => {
      setLastMessage(msg);
      console.log('收到消息:', msg);
    });

    // 监听连接错误
    newSocket.on('connect_error', (err) => {
      console.error('连接失败:', err);
    });

    setSocket(newSocket);

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

  return (
    <div>
      <p>最后收到的消息: {lastMessage || '无'}</p>
    </div>
  );
}

export default App;

2. 优化Next.js Socket.IO服务的配置

调整api/socket.ts的CORS配置,明确允许外部CRA应用的地址(比如CRA默认跑在http://localhost:3001),避免潜在跨域问题:

import { Server } from 'socket.io';
import type { NextApiRequest, NextApiResponse } from 'next';

// 扩展NextApiResponse类型,添加io属性
type NextApiResponseServerIO = NextApiResponse & {
  socket: {
    server: {
      io: Server;
    };
  };
};

export default function SocketHandler(_: NextApiRequest, res: NextApiResponseServerIO) {
  if (res.socket.server.io) {
    res.end();
    return;
  }

  const io = new Server(res.socket.server as any, {
    path: '/api/socket',
    cors: {
      origin: ['http://localhost:3001'], // 替换成你的CRA应用地址
      methods: ['GET', 'POST']
    }
  });
  res.socket.server.io = io;

  const onConnection = (socket: any) => {
    messageHandler(io, socket);
  };

  io.on('connection', onConnection);
  res.end();
}

function messageHandler(_: any, socket: any) {
  const createdMessage = (msg: string) => {
    console.log('createdMessage', msg);
    socket.broadcast.emit('newIncomingMessage', msg);
  };

  socket.on('createdMessage', createdMessage);
}

3. 测试流程

  1. 启动Next.js服务(默认localhost:3000)。
  2. 启动CRA应用(默认localhost:3001)。
  3. Next.js客户端发送消息后,CRA应用应该能收到newIncomingMessage事件的消息。

常见排查点

  • 确认两个应用的端口是否正确,Next.js默认3000,CRA默认3001,别搞混。
  • 检查Socket.IO服务的path配置,客户端和服务端必须一致。
  • 如果还是出现跨域错误,检查CORS配置的origin是否包含外部应用的地址,开发环境可以临时用*测试,但生产环境要指定具体域名。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 09:23:40