#Access socket instance within custom decorator

1 messages · Page 1 of 1 (latest)

quartz nimbus
#

I have this method that I want add an additional decorator to

  @SubscribeMessage('add')
  @HandleResponse();
  async add(@MessageBody() doc: Doc) {
    //do stuff
    return await this.service.update(....);
  }

I want to intercept this method with my custom decorator to be able to send an acknowledgement manually.

export function HandleResponse() {
  return function (
    target: any,
    propertyKey: string,
    descriptor: PropertyDescriptor,
  ) {
    const originalMethod = descriptor.value;

    descriptor.value = async function (...args: any[]) {
      const ctx: ExecutionContext = args[0];

      const client = ctx.switchToWs().getClient<Socket>(); 
      
     //error ctx.switchToWs is not a function
     //I wan to be able to call .emit() here

    };

    return descriptor;
  };
}

I wonder how can you access socket without changing params in a calling function, ref:https://stackoverflow.com/questions/73723999/custom-decorator-not-being-invoked-on-socket-message-handler-nestjs-socketio

Thoughts or any pointers to nestjs decorators that are leveraging socketsio so I can have a look?

UPDATE:

Just realized I can use @ConnectedSocket() client: Socket if I add that as an additional param, tho consuming code wont be changed as nestjs will inject client automatically. Then my decorator would look like

import { Socket } from 'socket.io';
import {HttpException} from '@nestjs/common';

export function HandleResponse() {
  return function (
    target: any,
    propertyKey: string,
    descriptor: PropertyDescriptor,
  ) {
    const originalMethod = descriptor.value;

    descriptor.value = async function (client: Socket, ...args: any[]) {
      try {
        const result = await originalMethod.apply(this, [client, ...args]);
        client.send(result);
      } catch (exception) {
        // handle error and client.send(....);
      }
    };

    return descriptor;
  };
}

is it the most optimal way in that case?

brittle valve
#

Why use a custom decorator instead of an interceptor where context: ExecutionContext is a guaranteed parameter and you can easily call emit before the return of intercept?