如何从控制器或其他组件/服务访问websocket?

时间:2019-01-17 23:03:10

标签: nestjs

我有一个REST API,我想通过websocket将事件发送给客户端。 如何在控制器或其他组件中注入websocket实例?

3 个答案:

答案 0 :(得分:2)

更好的解决方案是创建全局模块。然后,您可以从任何其他模块/控制器发出事件。 A.如果您尝试在其他模块中使用Afir方法,它将创建多个Gateway实例。

注意:这只是最简单的解决方案

创建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参见afterInit功能

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}`);
  }

}

然后将SocketModule导入AppModule,您可以在任何地方使用Socket service

答案 1 :(得分:0)

Gateway可以注入到另一个组件中,并使用服务器实例。

@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();
  }
}

答案 2 :(得分:0)

我想@Raold 错过了 documentation 中的一个事实:

<块引用>

网关不应使用请求范围的提供程序,因为它们必须充当单例。每个网关封装了一个真实的socket,不能被多次实例化。

所以这意味着我们既不能多次实例化网关类,也不能显式使用注入作用域特性。

因此,只为一个命名空间创建一个网关是正确的,它只会生成 websocket 或 socket.io 服务器的一个实例。