Reputation: 21
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/[email protected] (socket.io 4.8.1) for my backend (nest.js) and [email protected] 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:
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!
Upvotes: 1
Views: 51