Socketio on Angular+NestJS Failing Silently

Discussão em 'Angular' iniciado por Ethan Chua, Dezembro 24, 2024.

  1. Ethan Chua

    Ethan Chua Guest

    I am working on a beginner angular project and needed bidirectional communication between front- and backend and so I decided to use socket.io. I installed @nestjs/platform-socket.io@10.4.15 (socket.io 4.8.1) for my backend (nest.js) and socket.io-client@4.8.1 for my frontend (Angular). My code is as follows:

    Frontend:

    curent-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)),
    ]
    };

    Backend:

    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();

    When I serve the frontend, the browser hangs (spinning loading bar) with no errors in the console. The network inspect tab is also blank. However on the backend (Nest.js) logger I see the websocket connections being established when the browser is loaded:

    [​IMG]

    I have tested the backend with Postman and I am able to connect to the socket.io server. Therefore, I believe the issue is with the frontend. I suspect that there is a conflict between the websocket and the standard HTTP requests to load content to my page. However I lack the experience to figure out where the issue could be.

    I have tried the following to no avail: Receiving Error: xhr poll error socket.io client React, https://socket.io/docs/v4/handling-cors/

    My issue also seems similar to this: https://www.reddit.com/r/angular/comments/1d2x98d/connecting_websocket_via_ngxsocketio_makes_whole/

    My full code can be found here: https://github.com/RCPilot1604/Player-Piano-Server

    Thank you in advance for anything can can point me in the right direction!

    Continue reading...

Compartilhe esta Página