Spring 中调用 io() socket.io-client 函数时重复调用 onConnected()

问题描述 投票:0回答:1

我正在尝试使用 Spring boot 设置一个 Socket.IO 服务器,它也充当我的应用程序的 API。我有一个 Angular 前端,如下所示:

问题是当我调用服务进行连接时,它会调用 Spring 的 onConnected 方法两次。我尝试通过删除对 client.joinRoom(sessionCode) 方法的调用来简化它,但日志保持不变。

我的客户端或我设置 socket.io 服务器的方式是否有错误?

我尝试将重新连接事件添加到我的客户端,并删除事件“连接”。 我尝试使用节点服务器,它工作得很好,但是它太复杂了,无法在 3 个应用程序之间进行通信,我想在 Spring 中实现。

成分:

import { Component, HostBinding, OnInit } from "@angular/core";
import { FormBuilder, FormGroup, Validators } from "@angular/forms";
import { GameSessionService } from "../../services/game-session.service";
import { SocketService } from "../../services/socket.service";
import { GameSessionI } from "../../interfaces/GameSessionI";



@Component({
  selector: 'app-create-game',
  templateUrl: './create-game.page.html',
  styleUrl: './create-game.page.scss',
})
export class CreateGamePage implements OnInit {
  createGameForm: FormGroup;

  @HostBinding('class') class = 'tw-my-auto';
  colorPrimaryString: string = 'primary';
  colorGreyString: string = 'grey';
  username: string = '';

  constructor(fb: FormBuilder, private readonly gameSessionService : GameSessionService, private readonly socketService: SocketService) {
    this.createGameForm = fb.group({
      username: ['', Validators.required],
    });
  }

  ngOnInit(): void {}

  onSubmit() {
    this.gameSessionService.createGameSession(
      this.createGameForm.value.username,
    ).subscribe(
      (gameSession: GameSessionI) => {
        console.log(gameSession);
        this.socketService.connect(gameSession.code, gameSession.owner.id, gameSession.owner.name);
      },
    );
  }

  backButton(){
    this.socketService.disconnect();
  }
}

服务:

import { Injectable } from '@angular/core';
import { io } from 'socket.io-client';
import { LaunchSessionDTO } from '../model/socket/LaunchSessionDTO';
import { GameSessionService } from './game-session.service';

@Injectable({
  providedIn: 'root',
})
export class SocketService {
  socket: any;

  constructor(private readonly gameSessionService: GameSessionService) {
    
  }

  connect(sessionCode: string, userId: number, userName: string) {
    console.log(this.socket);
    if (!this.socket) {
      this.socket = io('http://localhost:9092', {
        transports: ['websocket'], // Specify transport for compatibility
        query: { sessionCode, userId, userName }, // Include handshake data
      });

      this.socket.on('connect', () => {
        console.log('Connected to socket server');
      });
      
      this.socket.on('disconnect', () => {
        console.log('Disconnected from socket server');
      });
    }
  }

  public launchSession(launchSessionDTO: LaunchSessionDTO) {
    this.socket.emit('launch_session', launchSessionDTO);
  }

  disconnect() {
    if (this.socket) {
      this.socket.disconnect();
    }
  }
}
package com.miage.beeramideback.socket.gamesession;

// imports

@Component
public final class GameSessionSocketModule {
    private final GameSessionBasicEventSocketService gameSessionSocketService;
    private final GameSessionService gameSessionService;
    private final GameSessionManagementService gameSessionManagementService;
    private final SocketIOServer server;
    Logger log = LoggerFactory.getLogger(GameSessionManagementServiceImpl.class);

    //Constructeur de la classe GameSessionSocketModule
    public GameSessionSocketModule(SocketIOServer server, GameSessionSocketServiceImpl gameSessionSocketServiceImpl, GameSessionManagementServiceImpl gameSessionManagementServiceImpl, GameSessionService gameSessionService) {
        this.server = server;
        this.gameSessionSocketService = gameSessionSocketServiceImpl;
        this.gameSessionManagementService = gameSessionManagementServiceImpl;
        this.gameSessionService = gameSessionService;
        //Ajout de Listener d'événements sur les parties en cours (réagit aux actions des clients connectés au serveur via le socket)
        server.addConnectListener(this.onConnected());
        server.addDisconnectListener(this.onDisconnected());
    }

    //Détecteur de l'événement de connection d'un joueur à la session
    private ConnectListener onConnected() {
        return (client) -> {
            final var params = client.getHandshakeData().getUrlParams();
            final String sessionCode = params.get("sessionCode").stream().collect(Collectors.joining());
            final Long userId = Long.parseLong(params.get("userId").stream().collect(Collectors.joining()));
            final String userName = params.get("userName").stream().collect(Collectors.joining());
            log.info("Socket connecting '{}'  ", client.getSessionId().toString());
        };
    }



    //Détecteur de l'événement de déconnection d'un joueur à la session
    private DisconnectListener onDisconnected() {
        return client -> {
            final var params = client.getHandshakeData().getUrlParams();
            final Long userId = Long.parseLong(params.get("userId").stream().collect(Collectors.joining()));
            final String sessionCode = client.getHandshakeData().getSingleUrlParam("sessionCode");
            final String userName = params.get("userName").stream().collect(Collectors.joining());
            log.info("Client '{}'' - disconnected from socket", client.getSessionId().toString());
        };
    }
}

以下是 spring 在前面调用 connect 时的日志: 日志

angular spring-boot socket.io socket.io-client netty-socketio
1个回答
0
投票

这似乎是库中的一个错误,解决方案是不要使用默认名称空间(“/”)并使用另一个名称空间,例如:

SocketIONamespace agentsNamespace = socketIOServer.addNamespace("/agents");

在客户端,使用此网址:

localhost:8090/agents
© www.soinside.com 2019 - 2024. All rights reserved.