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

Next.js前端连接Netty SocketIO Spring Boot后端出现404错误

Next.js 连接 Netty SocketIO Spring Boot 后端出现404错误

问题现象

浏览器控制台出现404错误,截图如下:
错误截图

用户代码片段

后端Spring Boot SocketIO配置

@Configuration
public class SocketIOConfig {
    @Bean
    public SocketIOServer socketIOServer() {
        com.corundumstudio.socketio.Configuration config = new com.corundumstudio.socketio.Configuration();
        config.setPort(8081);
        config.setOrigin("*");
        return new SocketIOServer(config);
    }
}

后端CORS与SocketIO事件逻辑

@Bean
public FilterRegistrationBean<CorsFilter> corsFilter() {
    FilterRegistrationBean<CorsFilter> registrationBean = new FilterRegistrationBean<>();
    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    CorsConfiguration config = new CorsConfiguration();
    config.addAllowedOrigin("*");
    config.addAllowedHeader("*");
    source.registerCorsConfiguration("/**", config);
    registrationBean.setFilter(new CorsFilter(source));
    registrationBean.setOrder(0);
    return registrationBean;
}

@Component
public class SocketIOServerRunner implements CommandLineRunner {
    private final SocketIOEvents socketIOEvents;

    @Autowired
    public SocketIOServerRunner(SocketIOEvents socketIOEvents) {
        this.socketIOEvents = socketIOEvents;
    }

    @Override
    public void run(String... args) {
        socketIOEvents.init();
    }
}

@Component
public class SocketIOEvents {
    private final SocketIOServer server;

    @Autowired
    public SocketIOEvents(SocketIOServer server) {
        this.server = server;
    }

    public void init() {
        server.addConnectListener(client -> {
            System.out.println("Client connected: " + client.getSessionId());
            server.getBroadcastOperations().sendEvent("messageFromServer", "Client connected: " + client.getSessionId());
        });

        server.addDisconnectListener(client -> {
            System.out.println("Client disconnected: " + client.getSessionId());
        });

        server.addEventListener("messageFromClient", String.class, (client, data, ackSender) -> {
            System.out.println("Received message: " + data);
            server.getBroadcastOperations().sendEvent("messageFromServer", data);
        });
    }
}

前端Next.js代码

"use client";

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

export default function Home() {
  const [input, setInput] = useState("");
  const [messages, setMessage] = useState<string[]>([]);

  const socket = io("http://localhost:8080");

  useEffect(() => {
    socket.on("connect", () => {
      console.log(socket.id);
    });

    socket.on("messageFromServer", (data) => {
      console.log(data);
      setMessage((oldArray) => [...oldArray, data.data]);
    });

    socket.io.on("reconnect", (data) => {
      console.log("reconnect event");
      console.log(data);
    });
  }, []);

  const onChangeHandler = (event: any) => {
    setInput(event.target.value);
  };

  return (
    <div style={{ display: "flex", flexDirection: "column" }}>
      <input type="text" onChange={onChangeHandler} value={input} />
      <button
        onClick={() => {
          console.log("here");
          socket.emit("messageFromClient", { data: input });
        }}>
        Submit
      </button>
      {messages.map((item, index) => {
        return <h5 key={`${index}`}>{item}</h5>;
      })}
    </div>
  );
}

问题分析与解决方案

1. 端口不匹配

后端SocketIO服务器配置的端口是8081,但前端连接的是8080,导致请求找不到服务。
修复:修改前端连接地址为正确端口:

const socket = io("http://localhost:8081");

2. SocketIO服务器未启动

后端代码仅配置了事件监听,但未调用server.start()启动服务器,导致服务未运行。
修复:在SocketIOEvents.init()方法末尾添加启动代码:

public void init() {
    // 现有事件监听代码...
    
    server.start();
    System.out.println("SocketIO server started on port 8081");
}

3. 事件数据格式不匹配

前端发送messageFromClient事件时传递的是对象{ data: input },但后端监听的是String.class类型,导致数据解析失败;同时前端接收时错误尝试读取data.data,但后端发送的是纯字符串。
修复:

  • 前端发送纯字符串:
socket.emit("messageFromClient", input);
  • 前端接收逻辑调整:
socket.on("messageFromServer", (data) => {
    console.log(data);
    setMessage((oldArray) => [...oldArray, data]);
});

4. 冗余CORS配置(可选优化)

后端SocketIO已经通过config.setOrigin("*")配置了跨域,无需再添加Spring的CorsFilter,重复配置可能引发冲突,可直接移除corsFilter() Bean。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 06:55:00