I'd like to create specific API route which will be used only WebSocket (/api/events
) but in all examples of implementing WebSockets on Nest.js I stumbled upon module is imported in AppModule
and client is emitting events toward the root URL, which I can't do because I have this middleware;
frontend.middleware.ts
import { Request, Response } from 'express';
import { AppModule } from '../../app.module';
export function FrontendMiddleware(
req: Request,
res: Response,
next: Function,
) {
const { baseUrl } = req;
if (baseUrl.indexOf('/api') === 0) {
next();
} else {
res.sendFile('index.html', { root: AppModule.getStaticAssetsRootPath() });
}
}
Here is the EventGateway
and EventModule
:
event.gateway.ts
import {
SubscribeMessage,
WebSocketGateway,
WebSocketServer,
WsResponse,
} from '@nestjs/websockets';
import { from, Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { Client, Server } from 'socket.io';
@WebSocketGateway({ namespace: 'events' })
export class EventGateway {
@WebSocketServer()
server: Server;
@SubscribeMessage('events')
findAll(client: Client, data: any): Observable<WsResponse<number>> {
return from([1, 2, 3]).pipe(map(item => ({ event: 'events', data: item })));
}
@SubscribeMessage('identity')
async identity(client: Client, data: number): Promise<number> {
return data;
}
}
event.module.ts
import { Module } from '@nestjs/common';
import { EventGateway } from './event.gateway';
@Module({
components: [EventGateway],
})
export class EventModule {}
Is there a way to create controller which will allow server-client communication via /api/events
?
Yes, it is possible to create the WebsocketGateway on another path. You can just use the options of the WebsocketGateway to configure the underlying IO-Connection:
E.g:
import {
SubscribeMessage,
WebSocketGateway,
WebSocketServer,
WsResponse,
} from '@nestjs/websockets';
import { from, Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { Client, Server } from 'socket.io';
@WebSocketGateway({ path: '/api/events', namespace: 'events' })
export class EventGateway {
@WebSocketServer()
server: Server;
@SubscribeMessage('events')
findAll(client: Client, data: any): Observable<WsResponse<number>> {
return from([1, 2, 3]).pipe(map(item => ({ event: 'events', data: item })));
}
@SubscribeMessage('identity')
async identity(client: Client, data: number): Promise<number> {
return data;
}
}
This will start the IO-Connection on http://localhost/api/events
Remember to change the connection-path also in your client. It won't be the default /socket.io path anymore, it will be /api/events in your sample.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With