How to access websocket from controller or another

2020-08-02 19:26发布

问题:

I have a REST API, I want to send event to the client via websocket. How to inject websocket instance in controller or another component?

回答1:

Better solution is to create global module. You can then emit events from any other module/controller. A. Afir approach will create multiple instances of Gateway if you try to use it in other modules.

Note: This is just simplest solution

Create socket.module.ts

import { Module, Global } from '@nestjs/common';
import { SocketService } from './socket.service';

@Global()
@Module({
 controllers: [],
 providers: [SocketService],
 exports: [SocketService],
})
export class SocketModule {}

socket.service.ts

import { Injectable } from '@nestjs/common';
import { Server } from 'socket.io';

@Injectable()
export class SocketService {

 public socket: Server = null;

}

app.gateway.ts see afterInit function

import { WebSocketGateway, OnGatewayInit, OnGatewayConnection, OnGatewayDisconnect, WebSocketServer } from '@nestjs/websockets';
import { Logger } from '@nestjs/common';
import { Server, Socket } from 'socket.io';
import { SocketService } from './socket/socket.service';

@WebSocketGateway()
export class AppGateway implements OnGatewayInit, OnGatewayConnection, OnGatewayDisconnect {

  constructor(private socketService: SocketService){

  }
  @WebSocketServer() public server: Server;
  private logger: Logger = new Logger('AppGateway');


  afterInit(server: Server) {
    this.socketService.socket = server;
  }

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

  handleConnection(client: Socket, ...args: any[]) {
    this.logger.log(`Client connected: ${client.id}`);
  }

}

Then import SocketModule into AppModule and you can use Socket service everywhere.



回答2:

class Gateway can be injected in another component, and use the server instance.

@Controller()
export class AppController {
  constructor(
    private readonly appService: AppService,
    private readonly messageGateway: MessageGateway
  ) {}

  @Get()
  async getHello() {
    this.messageGateway.server.emit('messages', 'Hello from REST API');
    return this.appService.getHello();
  }
}