#Injecting websocket gateway inside queue processor is a recommended way?

25 messages · Page 1 of 1 (latest)

leaden lodge
#

Hello everyone,

In my scenario, I generate signUrl to upload photo to s3 later and send each user inside current room via socket. To do so, I inject websocket gateway inside queue processor. But I don't know, is it nestjs recommended approach for using ws gateways.

// processor.ts
@Processor('moment-capture')
export class CaptureProcessor extends WorkerHost {
  constructor(
    private readonly s3Service: S3Service,
    private readonly momentGateway: MomentGateway,
  ) {
    super();
  }

  async process(job: Job<any, any, string>): Promise<any> {
    switch (job.name) {
      case CAPTURE_JOB: {
        const url = await this.s3Service.generatePresignedUrl('test')
          
        // emit unique url to each user via socket
        this.momentGateway.server.to('socketId').emit('sign_url', url);
      }
    }
  }
}
// gateway.ts
export class MomentGateway implements OnGatewayConnection, OnGatewayDisconnect {
  constructor() {}

  @WebSocketServer()
  server: Server;

  handleConnection(socket: Socket) {}
}

I would appreciate you recommendation and help ❤️🫡

night widget
#

like this

#
import { Injectable } from '@nestjs/common';
import { Processor, WorkerHost } from '@nestjs/bullmq';
import { EventEmitter2 } from '@nestjs/event-emitter';
import { S3Service } from './s3.service';

@Processor('moment-capture')
export class CaptureProcessor extends WorkerHost {
  constructor(
    private readonly s3Service: S3Service,
    private readonly eventEmitter: EventEmitter2, // Use event emitter
  ) {
    super();
  }

  async process(job: Job<any, any, string>): Promise<any> {
    switch (job.name) {
      case CAPTURE_JOB: {
        const url = await this.s3Service.generatePresignedUrl('test');

        // Emit an event instead of directly using the WebSocket Gateway
        this.eventEmitter.emit('moment.upload.url', { socketId: 'socketId', url });
      }
    }
  }
}
#

then, listen for events inside WebSocket gateway

#
import { WebSocketGateway, WebSocketServer, OnGatewayConnection, OnGatewayDisconnect } from '@nestjs/websockets';
import { Server, Socket } from 'socket.io';
import { Injectable, OnModuleInit } from '@nestjs/common';
import { EventEmitter2, OnEvent } from '@nestjs/event-emitter';

@Injectable()
@WebSocketGateway()
export class MomentGateway implements OnGatewayConnection, OnGatewayDisconnect, OnModuleInit {
  constructor(private readonly eventEmitter: EventEmitter2) {}

  @WebSocketServer()
  server: Server;

  onModuleInit() {
    console.log('WebSocket Gateway Initialized');
  }

  handleConnection(socket: Socket) {
    console.log(`Client Connected: ${socket.id}`);
  }

  handleDisconnect(socket: Socket) {
    console.log(`Client Disconnected: ${socket.id}`);
  }

  // Listen for the emitted event from the processor
  @OnEvent('moment.upload.url')
  handleUploadUrlEvent(payload: { socketId: string; url: string }) {
    console.log(`Sending URL to ${payload.socketId}`);
    this.server.to(payload.socketId).emit('sign_url', payload.url);
  }
}
leaden lodge
#

Yes, but In my scenario, I need to loop through a maybe thousand of connected users in the current room and emit to gateway and emit to client again. I think this will add additional stuffs and will cause performance instead of directly emitting to the client right? How do you think abt it?

night widget
#

instead of calling this.momentGateway.server.to('socketId').emit(...) inside your processor, you can emit an event and let the WebSocket gateway handle it

#

in your processor, generate the url and emit an event

leaden lodge
night widget
#

and in your WebSocket gateway, listen for that event and send the msg

#
@OnEvent('moment.upload.url')
handleUploadUrlEvent(payload: { socketId: string; url: string }) {
  this.server.to(payload.socketId).emit('sign_url', payload.url);
}
night widget
leaden lodge
night widget
#

using EventEmitter2 adds an extra step like emitting a local event before sending to clients, but in pracitce, it wont really hurt performance

night widget
leaden lodge
night widget
#

and it makes your system easier to maintain and test later

leaden lodge
night widget
#

so unless you are hitting performance bottlenecks, this approach is solid

#

just these are my some exp, and i hope this helps you well~~~~

leaden lodge
leaden lodge