我有一个REST API,我想通过websocket向客户端发送事件。 如何在控制器或其他组件中注入websocket实例?
我有一个REST API,我想通过websocket向客户端发送事件。 如何在控制器或其他组件中注入websocket实例?
更好的解决方案是创建全局模块。这样,您可以从任何其他模块/控制器中发出事件。如果您尝试在其他模块中使用它,则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}`);
}
}
然后在 AppModule 中导入 SocketModule
,这样你就可以在任何地方使用 Socket service
了。
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();
}
}
我想@Raold在文档中错过了一个事实:
网关不应使用请求范围的提供程序,因为它们必须充当单例。每个网关封装了一个真实的套接字,不能多次实例化。
这意味着我们既不能多次实例化网关类,也不能使用注入范围功能显式地进行实例化。
因此,为一个命名空间创建一个网关将是正确的,它将产生一个websocket或socket.io服务器的实例。