网关
本文档其他地方讨论的大多数概念,如依赖注入、装饰器、异常过滤器、管道、守卫和拦截器,也同样适用于网关。只要可能,Nest 就会抽象实现细节,以便相同的组件可以运行在基于 HTTP 的平台、WebSockets 和微服务上。本节涵盖了 Nest 中特定于 WebSockets 的方面。
在 Nest 中,网关只是一个使用 @WebSocketGateway() 装饰器注释的类。从技术上讲,网关是平台无关的,这使得它们在创建适配器后与任何 WebSockets 库兼容。开箱即用支持两个 WS 平台:socket.io 和 ws。您可以选择最适合您需求的一个。此外,您还可以按照此 指南 构建自己的适配器。

网关可以被视为 Providers;这意味着它们可以通过类构造函数注入依赖项。此外,网关也可以被其他类(提供者和控制器)注入。
安装
要开始构建基于 WebSockets 的应用程序,首先安装所需的包:
概述
通常,每个网关都在与 HTTP 服务器 相同的端口上监听,除非您的应用程序不是 Web 应用程序,或者您手动更改了端口。可以通过向 @WebSocketGateway(80) 装饰器传递一个参数来修改此默认行为,其中 80 是选定的端口号。您还可以使用以下构造设置网关使用的 命名空间:
在现有模块的 providers 数组中引用网关之前,它们不会被实例化。
您可以通过 @WebSocketGateway() 装饰器的第二个参数将任何受支持的 选项 传递给 socket 构造函数,如下所示:
网关现在正在监听,但我们尚未订阅任何传入消息。让我们创建一个处理器,它将订阅 events 消息并使用完全相同的数据响应用户。
@SubscribeMessage() 和 @MessageBody() 装饰器是从 @nestjs/websockets 包中导入的。
一旦创建了网关,我们就可以在我们的模块中注册它。
您还可以将属性键传递给装饰器以从传入消息正文中提取它:
如果您不想使用装饰器,以下代码在功能上是等效的:
在上面的示例中,handleEvent() 函数有两个参数。第一个是平台特定的 socket 实例,而第二个是从客户端接收的数据。但不推荐这种方法,因为它需要在每个单元测试中模拟 socket 实例。
一旦接收到 events 消息,处理器就会发送一个包含在网络上发送的相同数据的确认。此外,可以使用库特定的方法发射消息,例如,利用 client.emit() 方法。为了访问连接的 socket 实例,使用 @ConnectedSocket() 装饰器。
@ConnectedSocket() 装饰器是从 @nestjs/websockets 包中导入的。
但是,在这种情况下,您将无法利用拦截器。如果您不想响应用户,只需跳过 return 语句(或显式返回一个“假”值,例如 undefined)。
现在,当客户端按如下方式发射消息时:
handleEvent() 方法将被执行。为了监听从上述处理器内部发射的消息,客户端必须附加一个相应的确认监听器:
虽然从消息处理器返回值本质上会发送确认,但高级场景通常需要直接控制确认回调。
@Ack() 参数装饰器允许将 ack 回调函数直接注入消息处理器。
如果不使用装饰器,此回调将作为方法的第三个参数传递。
多个响应
确认仅调度一次。此外,原生 WebSockets 实现不支持它。为了解决此限制,您可以返回一个由两个属性组成的对象。event 是发射的事件名称,data 是必须转发给客户端的数据。
WsResponse 接口是从 @nestjs/websockets 包中导入的。
如果您的 data 字段依赖于 ClassSerializerInterceptor,则应该返回一个实现 WsResponse 的类实例,因为它会忽略纯 JavaScript 对象响应。
为了监听传入的响应,客户端必须应用另一个事件监听器。
异步响应
消息处理器能够以同步或 异步 方式响应。因此,支持 async 方法。消息处理器还能够返回一个 Observable,在这种情况下,结果值将被发射直到流完成。
在上面的示例中,消息处理器将响应 3 次(数组中的每个项目对应一次)。
生命周期钩子
有 3 个有用的生命周期钩子可用。它们都有相应的接口,并在下表中进行了描述:
每个生命周期接口均从 @nestjs/websockets 包中公开。
服务器和命名空间
有时,您可能希望直接访问原生的、平台特定 的服务器实例。对此对象的引用作为参数传递给 afterInit() 方法(OnGatewayInit 接口)。另一种选择是使用 @WebSocketServer() 装饰器。
此外,您可以使用 namespace 属性检索相应的命名空间,如下所示:
@WebSocketServer() 装饰器通过引用 @WebSocketGateway() 装饰器存储的元数据来注入服务器实例。如果您为 @WebSocketGateway() 装饰器提供了命名空间选项,则 @WebSocketServer() 装饰器将返回 Namespace 实例而不是 Server 实例。
@WebSocketServer() 装饰器是从 @nestjs/websockets 包中导入的。
一旦服务器实例准备就绪,Nest 将自动将其分配给此属性。
示例
一个工作的例子可以在这里查看。

