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

Angular+NestJS中Socket.io无报错静默失败问题排查

Angular + Nest.js Socket.io 连接导致页面挂起问题

我正在开发一个入门级Angular项目,需要实现前后端双向通信,因此选择使用Socket.io。后端(Nest.js)安装了@nestjs/platform-socket.io@10.4.15(对应socket.io 4.8.1),前端(Angular)安装了socket.io-client@4.8.1。

启动前端服务后,浏览器出现挂起状态(加载栏持续旋转),控制台无任何错误输出,网络面板也为空。但后端(Nest.js)日志显示,浏览器加载时WebSocket连接已成功建立。

用Postman测试后端能正常连接到Socket.io服务器,因此判断问题出在前端。怀疑WebSocket连接与页面加载的标准HTTP请求存在冲突,但缺乏经验无法定位具体原因。

前端代码

current-song.component.ts

import { Component, Input, OnInit, OnDestroy, inject} from '@angular/core';
import { SongEntry } from '../song-entry';
import { NgIf } from '@angular/common';
import { WebsocketService } from './websocket.service';
import { FormsModule } from '@angular/forms';

@Component({
  selector: 'app-current-song',
  standalone: true,
  imports: [NgIf, FormsModule],
  providers: [WebsocketService],
  templateUrl: './current-song.component.html',
  styleUrls: ['./current-song.component.css']
})
export class CurrentSongComponent implements OnInit, OnDestroy {
  @Input() song: SongEntry | null = null;
  isPlaying = false;
  currentTime = 0;
  duration = 100; // Initialize duration to 0
  volume = 50;
  socket: WebsocketService = inject(WebsocketService);
  constructor() {
    
  }
  ngOnInit() {
    this.socket.fromEvent('connected').subscribe(() => {
      console.log('Connected to server');
    });
    this.socket.fromEvent('connect_error').subscribe((err) => {
      console.log('Error connecting to server: ', err);
    });
  }
  ngOnDestroy(): void {
    this.socket.disconnect();
  }
}

websocket.service.ts

// src/app/services/socket.service.ts
import { Injectable } from '@angular/core';
import { Socket } from "ngx-socket-io";
import { Observable } from 'rxjs';

@Injectable()
export class WebsocketService {
  constructor(private socket:Socket) {
  }

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

  fromEvent(event: string): Observable<any>{
    return this.socket.fromEvent(event);
  }
  disconnect() {
    this.socket.disconnect();
  }
}

app.config.ts

import { ApplicationConfig, provideZoneChangeDetection, importProvidersFrom } from '@angular/core';
import { provideRouter } from '@angular/router';
import { provideHttpClient, withFetch } from '@angular/common/http';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { MatListModule } from '@angular/material/list';
import { MatSnackBarModule } from '@angular/material/snack-bar';

import { routes } from './app.routes';
import { provideClientHydration, withEventReplay } from '@angular/platform-browser';
import { provideAnimationsAsync } from '@angular/platform-browser/animations/async';
import { SocketIoModule, SocketIoConfig } from 'ngx-socket-io';
const config: SocketIoConfig = { url: 'ws://localhost:1234' };

export const appConfig: ApplicationConfig = {
  providers: [
    provideZoneChangeDetection({ eventCoalescing: true }),
    provideRouter(routes),
    provideHttpClient(withFetch()), 
    provideClientHydration(withEventReplay()), provideAnimationsAsync(),
    importProvidersFrom(SocketIoModule.forRoot(config)),
  ]
};

后端代码

midi-player.gateway.ts

import {
  WebSocketGateway,
  WebSocketServer,
  SubscribeMessage,
  OnGatewayConnection,
  OnGatewayInit,
  OnGatewayDisconnect,
  MessageBody,
} from '@nestjs/websockets';
import { Server } from 'socket.io';
import { Logger } from '@nestjs/common';
//import * as MidiPlayer from 'midi-player-js';

@WebSocketGateway(1234)
export class MidiPlayerGateway implements OnGatewayInit, OnGatewayConnection, OnGatewayDisconnect{
  private readonly logger = new Logger(MidiPlayerGateway.name);
  private interval: NodeJS.Timeout;

  @WebSocketServer()
  server: Server;
  afterInit() {
    this.logger.log("Initialized");
  }

  handleConnection(client: any, ...args: any[]) {
    this.logger.log(`Client id:${client.id} connected`);
  }

  handleDisconnect(client: any) {
    this.logger.log(`Cliend id:${client.id} disconnected`);
  }
}

main.ts

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
async function bootstrap() {
  const app = await NestFactory.create(AppModule,
    {
      snapshot: true,
    }
  );
  await app.listen(process.env.PORT ?? 3000);
}
bootstrap();

已尝试方案

  • 参考了Socket.io CORS处理相关内容
  • 查看了React项目中Socket.io XHR轮询错误的解决方案
  • 发现问题与Angular社区中提到的ngx-socket-io导致页面整体挂起的案例类似

希望能得到定位问题方向的建议。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 08:04:53