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

Angular向Java Spring Boot Socket.IO服务端收发事件失败求助

问题描述

我在Angular 14应用中尝试向Java Spring Boot的Socket.IO服务端发送事件,目前应用能正常连接服务端,Java端也能捕获连接、断开事件,但无法向服务端发送事件,也接收不到服务端推送的事件。

使用版本:Angular 14、Java 11
预期结果:服务端能接收客户端发送的事件,客户端能收到服务端发送的事件内容


Java服务端代码(原代码)

public class SocketIOServerImpl {

    public static void main(String[] args) throws InterruptedException {
        Configuration config = new Configuration();
        config.setHostname("localhost");
        config.setPort(8090);
websocket
        final SocketIOServer server = new SocketIOServer(config);

        server.addConnectListener(socketIOClient -> {
            System.out.println("User Connected");
            server.getBroadcastOperations().sendEvent("daniyal", "You Connected to Server Successfully");
        });

        server.addDisconnectListener(client -> {
            server.getBroadcastOperations().sendEvent("daniyal", "You Connected to Server Successfully");
        });

        server.addEventListener("daniyal", String.class, new DataListener<String>() {

            @Override
            public void onData(SocketIOClient socketIOClient, String s, AckRequest ackRequest) throws Exception {
                System.out.println("User Connected");
                server.getBroadcastOperations().sendEvent("daniyal", "You Emited STH to Server Successfully");
            }
        });

        server.start();
        Thread.sleep(Integer.MAX_VALUE);

        server.stop();
    }
}

Angular Socket服务代码(原代码)

@Injectable({
  providedIn: 'root'
})
export class SocketServiceService {

  readonly uri: string = 'ws://localhost:8090';
  socket: any;

  constructor() {
    this.socket = io.connect(this.uri,{ transports: [ 'websocket' ] });
  }


  listen(eventName: string) {
    return new Observable((subscriber) => {
      this.socket.on(eventName, (data: any) => {
        subscriber.next(data);
      });
    });
  }

  emit(eventName: string, data: any) {
    this.socket.emit(eventName, data);
  }
}

Angular组件代码(原代码)

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {

  constructor(private socketService: SocketServiceService) {
  }

  ngOnInit() {
    this.socketService.listen('daniyal').subscribe(
      (res) => {
        console.log('Server Response: ',res);
      });
  }

  emit(){
    this.socketService.emit('daniyal','HI SERVER');
  }
}

问题排查与修复方案

核心问题:版本兼容性

Socket.IO的协议在不同大版本间不兼容,必须保证Java端的netty-socketio版本与Angular端的socket.io-client版本完全匹配(比如均为2.x版本)。

具体修改点

1. Java服务端修改

  • 移除代码中多余的websocket字符串(会导致配置错误)
  • 修正断开连接事件的错误消息
  • 事件监听中打印正确的客户端消息日志
  • 针对当前连接客户端发送事件(而非广播给所有用户,除非业务需要)
  • 确保Maven依赖使用兼容版本(比如2.5.0):
<dependency>
    <groupId>com.corundumstudio.socketio</groupId>
    <artifactId>netty-socketio</artifactId>
    <version>2.5.0</version>
</dependency>

修改后的Java代码:

public class SocketIOServerImpl {

    public static void main(String[] args) throws InterruptedException {
        Configuration config = new Configuration();
        config.setHostname("localhost");
        config.setPort(8090);

        final SocketIOServer server = new SocketIOServer(config);

        server.addConnectListener(socketIOClient -> {
            System.out.println("User Connected");
            // 仅向当前连接的客户端发送事件
            socketIOClient.sendEvent("daniyal", "You Connected to Server Successfully");
        });

        server.addDisconnectListener(client -> {
            System.out.println("User Disconnected");
            client.sendEvent("daniyal", "You Disconnected from Server");
        });

        server.addEventListener("daniyal", String.class, (socketIOClient, s, ackRequest) -> {
            System.out.println("Received message from client: " + s);
            // 回复当前客户端
            socketIOClient.sendEvent("daniyal", "You Emitted STH to Server Successfully");
        });

        server.start();
        Thread.sleep(Integer.MAX_VALUE);
        server.stop();
    }
}

2. Angular端修改

  • 将连接地址改为http://localhost:8090(Socket.IO会自动处理协议升级为WebSocket)
  • 安装与Java端匹配的socket.io-client版本:npm install socket.io-client@2.5.0
  • 添加连接错误监听,方便排查问题

修改后的Socket服务代码:

import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import * as io from 'socket.io-client';

@Injectable({
  providedIn: 'root'
})
export class SocketServiceService {

  readonly uri: string = 'http://localhost:8090';
  socket: any;

  constructor() {
    this.socket = io.connect(this.uri, { transports: ['websocket'] });
    
    // 监听连接错误
    this.socket.on('connect_error', (error: any) => {
      console.error('Socket connection error:', error);
    });
    
    // 监听连接成功
    this.socket.on('connect', () => {
      console.log('Connected to server');
    });
  }

  listen(eventName: string): Observable<any> {
    return new Observable((subscriber) => {
      this.socket.on(eventName, (data: any) => {
        subscriber.next(data);
      });
    });
  }

  emit(eventName: string, data: any): void {
    this.socket.emit(eventName, data);
  }
}

3. 组件模板补充(可选)

在app.component.html中添加触发按钮,方便测试发送事件:

<button (click)="emit()">Send Message to Server</button>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 00:50:27