网关¶
本文档中讨论的大多数概念,如依赖注入、装饰器、异常过滤器、管道、守卫和拦截器,都同样适用于网关。 只要有可能,Nest 会抽象实现细节,这样相同的组件就可以在基于 http 的平台、WebSockets 和 Microservices 上运行。 本节将介绍 Nest 特有的 WebSockets 方面。
在 Nest 中,网关只是一个带有@WebSocketGateway()
装饰器注释的类。
从技术上讲,网关是平台无关的,这使得一旦创建了适配器,网关就与任何 WebSockets 库兼容。
有两个现成的 WS 平台受支持:socket.io和ws。
您可以选择最适合您需要的。
同样,您可以通过以下指南构建自己的适配器.
Hint
网关可以被视为providers; 这意味着它们可以通过类构造函数注入依赖项。 另外,网关也可以被其他类(提供程序和控制器)注入。
安装¶
要开始构建基于 websocket 的应用程序,首先要安装所需的包:
概述¶
通常情况下,每个网关都在同一个端口上监听 HTTP 服务器 ,除非你的应用不是 web 应用,或者你已经手动更改了端口。
这个默认行为可以通过传递一个参数给@WebSocketGateway(80)
装饰器来修改,其中80
是选定的端口号。
您还可以使用以下结构设置网关使用的namespace:
Warning
网关只有在现有模块的提供器数组中引用它们时才被实例化。
您可以将任何受支持的选项传递给套接字构造函数,并将第二个参数传递给@WebSocketGateway()
装饰器,如下所示:
网关现在正在收听,但是我们还没有订阅任何传入的消息。
让我们创建一个处理程序,它将订阅events
消息并以完全相同的数据响应用户。
@SubscribeMessage()
和@MessageBody()
装饰器是从@nestjs/websockets
包中导入的.
一旦创建了网关,我们就可以在我们的模块中注册它。
events.module.ts | |
---|---|
您还可以将一个属性键传递给装饰器,以便从传入的消息体中提取它
如果不喜欢使用装饰器,下面的代码在功能上是等价的:
在上面的例子中,handleEvent()
函数接受两个参数。
第一个是平台特定的套接字实例,而第二个是从客户端接收的数据。
但是不推荐这种方法,因为它需要在每个单元测试中模拟socket
实例。
一旦接收到 events
消息,处理程序将使用通过网络发送的相同数据发送一个确认。
此外,还可以使用特定于库的方法发出消息,例如使用client.emit()
方法。
为了访问已连接的套接字实例,请使用@ConnectedSocket()
装饰器。
@ConnectedSocket()
装饰器是从@nestjs/websockets
包导入的。
然而,在这种情况下,您将无法利用拦截器。
如果你不想响应用户,你可以简单地跳过return
语句(或者显式地返回falsy
值,例如undefined
)。
现在,当客户机发出如下消息时:
handleEvent()
方法将被执行。
为了监听从上面的处理程序中发出的消息,客户端必须附加一个相应的确认监听器:
多个响应¶
确认只被发送一次。
此外,原生 WebSockets 实现也不支持它。
为了解决这个限制,你可以返回一个包含两个属性的对象。
event
是发出事件的名称,以及必须转发给客户端的data
。
WsResponse
接口是从@nestjs/websockets
包导入的。
Warning
如果你的data
字段依赖于ClassSerializerInterceptor
,你应该返回一个实现WsResponse
的类实例,因为它忽略了普通的 JavaScript 对象响应。
为了监听传入的响应,客户机必须应用另一个事件侦听器。
异步响应¶
消息处理程序能够同步响应或 异步响应 。
因此,支持async
方法。
消息处理程序还可以返回一个Observable
,在这种情况下,结果值将一直发出,直到流完成。
在上面的例子中,消息处理程序将响应 3 次 (对于数组中的每个项)。
生命周期的钩子¶
有 3 个有用的生命周期钩子可用。它们都有相应的接口,下表对此进行了描述:
OnGatewayInit
|
强制实现afterInit() 方法。
将特定于库的服务器实例作为参数(并在需要时传播其他参数)。
|
OnGatewayConnection
|
强制实现handleConnection() 方法.
将特定于库的客户机套接字实例作为参数。
|
OnGatewayDisconnect
|
强制实现handleDisconnect() 方法.
将特定于库的客户机套接字实例作为参数。
|
每个生命周期接口都是从@nestjs/websockets
包中公开的。
服务器¶
有时候,你可能想直接接触本地, 特定于平台 的服务器实例.
对该对象的引用作为参数传递给afterInit()
方法(OnGatewayInit
接口)。
另一个选项是使用@WebSocketServer()
装饰器。
Warning
@WebSocketServer()
装饰器是从@nestjs/websockets
包中导入的。
一旦服务器实例准备好使用,Nest 将自动将其分配给该属性。
例子¶
一个可用的示例在这里.