Búsqueda de sitios web

typescript - El decorador SubcribeMessage no se activa en el evento 'message'


Estoy configurando un servidor WebSocket en mi backend de NestJS, y cuando intento suscribirme al tipo de evento predeterminado 'message', el método handleMessage() no se activa.

El método listenForMessages(), sin embargo, funciona (el cual se activa después de la inicialización del servidor). ¿Alguien sabe por qué el decorador @SubscribeMessage('message') no funciona?

@WebSocketGateway()
export class AppWebsocketGateway implements OnGatewayInit, OnGatewayDisconnect {
  private clientIds = new Map<string, string>();
  // @ts-ignore
  @WebSocketServer() server: Server;
  private logger: Logger = new Logger('WebsocketGateway');

  constructor(private readonly evseService: EvseService) {
  }

  listenForMessages() {
    this.server.on('connection', (ws) => {
      ws.on('message', (e) => {
        console.log(e);
      });
    });
    this.logger.log('message received');
  }


  @SubscribeMessage('message')
  handleMessage(@ConnectedSocket() client: any, payload: any): void {
    this.logger.log('I received a message from the client!');
    this.server.emit('msgToClient', payload);
  }

  afterInit(server: Server) {
    this.logger.log('Init');
    this.listenForMessages();
  }

  handleDisconnect(@ConnectedSocket() client: any) {
    this.logger.log(`Client disconnected: ${client.id}`);
  }
}

Respuesta #1

//@SubscribeMessage('message') will look for the message that are in the format :
{
  event:'message',
  data: {someData} // Whatever in the data field will be the payload in 
                   //handleMessage()
}

// Another example 
// @SubscribeMessage('get_profile') will look for messages in the format : 

{
  event:'get_profile',
  data: {someData} // Whatever in the data field will be the payload in 
                   //handleMessage()
}

Entonces, ¿por qué @SubscribeMessage('message') necesita tal formato? Bueno, para aprovechar las funcionalidades de NestJS como interceptores, pipes, etc. Si implementas tal formato para los mensajes entrantes (eventos), en el futuro no tendrías que cambiar la lógica del manejador incluso si cambias la librería a socket.io o μWebsocket.js o tu propia implementación para websockets. Solo necesitas implementar tu propio adaptador de websocket personalizado.

En resumen, NestJS se asegura de que tu código diga lo mismo incluso si la tecnología subyacente cambia.

El listenForMessages() adjunta directamente un oyente en el servidor. Este es un enfoque específico de la biblioteca y necesitarías cambiar toda la lógica del oyente si decides cambiar la biblioteca a: por ejemplo, socket.io.

ws.on('message', callback);, registrará lo que el socket envíe (según tu código en listenForMessages()), sin importar el formato, es decir: puedes enviar una cadena, buffer, JSON, etc., pero para @SubscribeMessage(<event>) debe estar en el formato :

{
event : <event>,
data : <any>, // Can be string, number, object, buffer, whatever you want
}

ws - es un socket que está conectado en el servidor.

Artículos relacionados