expressnestjsbackendstate-management

How to get HTTP request, then share the info with a Gateway provider. Nest.js


Task:
I'm trying to get HTTP request that the user leaves the chat room. This information ought to be shared with others in this chat. To be more precise, step by step:

  1. the user clicks button "leave room X-name-room";
  2. front end sends an HTTP request;
  3. here is some logic that allows the user to leave the room
  4. the HTTP controller transmits information about the HTTP request to the websocket service(Nest.Gateway)
  5. the Ws service sends a message "user-leave-a-room" event to the participants of the room;
  6. an http response is sent to the user, who left the room.

Problem:
I can't find information about the data exchange between Nest.Controller and Nest.Gateways(ws).

Prerequisites:
Now I just do it only via Websocket event. But in this case, the user interface cannot know the exact time, when the user left a room. (an HTTP request can be awaited via promises, and websocket event - can't).

Workaround:
Front end sends an HTTP request to leave a room. Awaiting a response. Then sends a socket event to notify the room participants. But the interface hasn't to care of other local machines of the service users - this is wrong. This task should be up to server side.

Thanks a lot for your answers.


Solution

  • So, I've found a solution to the problem: Nest.js allows you to simply integrate Nest.Gateways into other classes, including Nest.Controllers. In this way, we can:

    1. receive an HTTP request
    2. process this one
    3. send out socket events
    4. return an HTTP response

    Simplified code:

    // events.gateway.ts file
    import { SubscribeMessage, WebSocketGateway, OnGatewayConnection, OnGatewayDisconnect } from '@nestjs/websockets';
    
    @WebSocketGateway()
    export class EventsGateway implements OnGatewayConnection, OnGatewayDisconnect {
      handleConnection(client: any, ...args: any[]) {
        console.log('Client connected:', client.id);
      }
    
      handleDisconnect(client: any) {
        console.log('Client disconnected:', client.id);
      }
    
      @SubscribeMessage('msgToServer')
      handleMessage(client: any, payload: string): string {
        return 'Message received: ' + payload;
      }
    }
    
    
    // room.controller.ts file
    import { Controller, Post, Body, HttpCode, HttpStatus } from '@nestjs/common';
    import { EventsGateway } from './events.gateway';
    
    @Controller('room')
    export class RoomController {
      // here we just inject the SocketGateway service
      constructor(private eventsGateway: EventsGateway) {}
    
      // when a user leaves a room:
    
      // P.S: you should get the userId from the sessions or JWT tokens. I've 
      // included the 'userId' field in the request.Body just for clarity.
      @Delete('leave')
      @HttpCode(HttpStatus.OK)
      leaveRoom(@Body() data: { roomId: string, userId: string }) {
        this.eventsGateway.server
            .to(roomId)
            .emit('room:user-leaves', data.message);
      }
    }