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

Spring中Netty Socket.IO替代Express Socket.IO实现数据推送问题

问题

我需要在Spring后端向前端Angular推送数据,但基于Netty的Socket.IO实现无法正常工作。目前代码里,ConnectListener能监听到客户端连接并打印日志,但getAllDashboardData对应的DataListener从未触发;而用Express实现的Socket.IO示例却能正常响应前端的getAllDashboardData事件。我已经用Postman测试过后端接口没问题,请问怎么在Spring里实现和这个Express等效的功能?

现有代码

Spring端代码

public ConnectListener onUserConnectWithSocket = new ConnectListener() {
        @Override
        public void onConnect(SocketIOClient socketIOClient) {
            log.info("Client connected: " + socketIOClient.getSessionId());
            socketIOClient.sendEvent("getAllDashboardData", generateRandomValues());
        }
    };

public DataListener<String> getAllDashboardData = new DataListener<String>() {
        @Override
        public void onData(SocketIOClient socketIOClient, String message, AckRequest ackRequest) throws Exception {
            log.info("Message received: " + message);
            socketIOClient.sendEvent("getAllDashboardData", generateRandomValues().toString());
        }
    };

Express端代码

module.exports = (io) => {
    io.on('connect', (socket) => {
        console.log('user connected');
        socket.on('getAllDashboardData', (data) => {
            //send some data to client back
            socket.emit('getAllDashboardData', {data: 'data'});
        });
        socket.on('disconnect', () => {
            console.log('user disconnected');
        });
    });
}

解决方案

你的核心问题是没有把getAllDashboardData对应的DataListener注册到Socket.IO服务器上——Express里通过socket.on()绑定了事件监听,但Spring端你只定义了DataListener,却没告诉服务器要监听这个事件。

修复步骤

  1. 注册事件监听器:在Socket.IO服务器初始化时,调用addEventListener方法,把你的getAllDashboardData监听器绑定到对应事件上
  2. 确保事件名称完全匹配:事件名称大小写、拼写必须和前端、Express代码里的完全一致
  3. 区分主动推送和响应请求:ConnectListener里的sendEvent是连接时主动推数据,和响应客户端触发的getAllDashboardData请求是两个逻辑,可以保留但不要混淆

修改后的Spring示例代码

import com.corundumstudio.socketio.Configuration;
import com.corundumstudio.socketio.ConnectListener;
import com.corundumstudio.socketio.DataListener;
import com.corundumstudio.socketio.SocketIOClient;
import com.corundumstudio.socketio.SocketIOServer;
import com.corundumstudio.socketio.AckRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.Map;

@Configuration
public class SocketIOConfig {
    private static final Logger log = LoggerFactory.getLogger(SocketIOConfig.class);

    @Bean
    public SocketIOServer socketIOServer() {
        Configuration config = new Configuration();
        config.setHostname("localhost");
        config.setPort(9092); // 确保和前端连接的端口一致
        
        SocketIOServer server = new SocketIOServer(config);
        
        // 注册连接监听
        server.addConnectListener(onUserConnectWithSocket);
        // 关键:注册getAllDashboardData事件的监听器,对应Express里的socket.on
        server.addEventListener("getAllDashboardData", String.class, getAllDashboardData);
        
        server.start();
        return server;
    }

    private ConnectListener onUserConnectWithSocket = new ConnectListener() {
        @Override
        public void onConnect(SocketIOClient socketIOClient) {
            log.info("Client connected: " + socketIOClient.getSessionId());
            // 可选:客户端连接时主动推送数据
            socketIOClient.sendEvent("getAllDashboardData", generateRandomValues());
        }
    };

    private DataListener<String> getAllDashboardData = new DataListener<String>() {
        @Override
        public void onData(SocketIOClient socketIOClient, String message, AckRequest ackRequest) throws Exception {
            log.info("Message received: " + message);
            // 响应客户端的getAllDashboardData请求,推送数据
            socketIOClient.sendEvent("getAllDashboardData", generateRandomValues().toString());
        }
    };

    // 示例生成随机数据的方法
    private Object generateRandomValues() {
        return Map.of("value1", Math.random(), "value2", Math.random());
    }
}

关键说明

  • Express中的socket.on('getAllDashboardData', ...),对应Spring里的server.addEventListener("getAllDashboardData", String.class, getAllDashboardData)
  • 如果使用的是封装后的Spring Boot Socket.IO Starter,注册逻辑可能略有不同,但核心都是将事件监听器绑定到服务器实例上
  • 测试时确保前端触发getAllDashboardData事件的代码和Express版本完全一致,避免事件名称不匹配的问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 03:10:16