【问题标题】:How to inject ConnectedSocket into a service in NestJS如何将 ConnectedSocket 注入 NestJS 中的服务
【发布时间】:2020-06-23 03:44:40
【问题描述】:

我想将@ConnectedSocket 注入到提供事件发射接口的nestjs 服务中。目标非常明确 - 避免使用原始事件名称和 any 数据调用发出。以下SocketFacadeHost 是此类服务的一个示例。

到目前为止,我能想到的唯一方法是通过使用外观服务工厂包装套接字来替换每个发出调用 - SocketFacade

socket.facade.ts

class SocketFacadeHost {
  constructor(private client: Socket) { }

  syncDSL(dsl: CoreDSL): void {
    this.client.emit('syncDSL', dsl);
  }
}

export const SocketFacade = (client: Socket) => new SocketFacadeHost(client);

socket.gateway.ts

  ...

  @SubscribeMessage('bind')
  async bindEnvironment(
    @MessageBody() data: BindingDTO,
    @ConnectedSocket() client: Socket,
  ): Promise<void> {
    const { pageUUID } = data;
    const page = await this.pagesService.getByUUID(pageUUID);
    SocketFacade(client).syncDSL(page.coreDSL);
  }

但这仍然有点骇人听闻。有什么直接的方法吗?

类似于扩展@ConnectedSocket 装饰器或WebSocketGateway

--- 编辑 1 ---

在阅读了大量有关该主题的文档、示例和问题后,我认为问题在于让服务了解上下文的想法,默认情况下这是不正确的。因此,守卫、拦截器、管道和所有 ExecutionContext 装饰器仅在控制器/网关级别上工作。服务应该是无状态的或在每次调用时全部实例化(由@Injectable 范围控制)。

所以我使用门面工厂的方法是可以的。

但是话又说回来,如果可以用一个装饰器“替换”@ConnectedSocket() 装饰器,该装饰器返回带有接口的包装套接字,那将不会与干净的 mvc 混淆。

【问题讨论】:

    标签: websocket nestjs


    【解决方案1】:

    最后,我决定破解我自己的“依赖注入”。由于WebSocketGateway 不能选择请求范围,因此我决定手动实例化和清理所需的服务,并将它们存储在具有额外存储接口的Socket 客户端中。

    这样我就有了ConnectedSocket-scoped 类,它们可以相互通信,同时仍然可以访问全局作用域注入(必须通过网关手动传递给所有类)。

    给定的方法解决了所有问题,同时保持一切干燥并与有一天ConnectedSocket-scopes 可能会添加到NestJS 的想法保持同步。

    【讨论】:

      猜你喜欢
      • 2018-11-16
      • 2020-09-09
      • 1970-01-01
      • 2020-06-06
      • 1970-01-01
      • 1970-01-01
      • 2022-09-24
      • 2019-04-25
      • 2021-12-29
      相关资源
      最近更新 更多