适配器

适配器

WebSockets模块基于socket.io 包,但您可以通过使用WebSocketAdapter接口来引入自己的库(甚至是本机实现)。此接口强制实现下表中描述的几个方法:

create基于传递的参数创建套接字实例
bindClientConnect绑定客户端连接事件
bindClientDisconnect绑定客户端断开连接事件(可选*)
bindMessageHandlers将传入消息绑定到相应的消息处理程序
close终止服务器实例

扩展socket.io

socket.io包裹在一个IoAdapter类中。如果您想增强适配器的基本功能,该怎么办?例如,您的技术要求需要能够跨Web服务的多个负载平衡实例广播事件。为此,您可以扩展IoAdapter和覆盖单个方法,该方法的任务是实例化新的socket.io服务器。但首先,让我们安装所需的包。

$ npm i --save socket.io-redis

安装包后,我们可以创建一个RedisIoAdapter类。

import { IoAdapter } from '@nestjs/websockets'; import * as redisIoAdapter from 'socket.io-redis'; const redisAdapter = redisIoAdapter{ host: 'localhost', port: 6379 } export class RedisIoAdapter extends IoAdapter { createIOServer(port: number, options?: any): any { const server = super.createIOServer(port, options server.adapter(redisAdapter return server; } }

然后,只需切换到新创建的Redis适配器。

const app = await NestFactory.create(ApplicationModule app.useWebSocketAdapter(new RedisIoAdapter(app)

Ws图书馆

另一个内置适配器WsAdapter反过来充当框架之间的代理,并集成了快速且经过全面测试的ws库。此适配器与本机浏览器WebSockets完全兼容,并且比socket.io包快得多。不幸的是,它具有明显更少的开箱即用功能。在某些情况下,你可能只是不需要它们。

const app = await NestFactory.create(ApplicationModule app.useWebSocketAdapter(new WsAdapter(app)

提示WsAdapter是进口@nestjs/websockets

高级(自定义适配器)

出于演示目的,我们将手写集成ws库。如前所述,此库的适配器已创建,并@nestjs/websockets作为WsAdapter类从包中公开。以下是简化实现的潜力:

WS-adapter.ts

JS

import * as WebSocket from 'ws'; import { WebSocketAdapter, MessageMappingProperties, INestApplicationContext } from '@nestjs/common'; import { Observable, fromEvent, empty } from 'rxjs'; import { mergeMap, filter, tap } from 'rxjs/operators'; export class WsAdapter implements WebSocketAdapter { constructor(private readonly app: INestApplicationContext) {} create(port: number, options: any = {}): any { return new ws.Server{ port, ...options } } bindClientConnect(server, callback: (...args) => void) { server.on('connection', callback } bindMessageHandlers( client: WebSocket, handlers: MessageMappingProperties[], process: (data: any) => Observable<any>, ) { fromEvent(client, 'message') .pipe( mergeMap(data => this.bindMessageHandler(data, handlers, process)), filter(result => result), ) .subscribe(response => client.send(JSON.stringify(response)) } bindMessageHandler( buffer, handlers: MessageMappingProperties[], process: (data: any) => Observable<any>, ): Observable<any> { const message = JSON.parse(buffer.data const messageHandler = handlers.find( handler => handler.message === message.event, if (!messageHandler) { return empty; } return process(messageHandler.callback(message.data) } close(server) { server.close( } }

提示如果要利用ws库,请使用内置WsAdapter而不是创建自己的库。

然后,我们可以使用useWebSocketAdapter()方法设置自定义适配器:

main.ts

JS

const app = await NestFactory.create(ApplicationModule app.useWebSocketAdapter(new WsAdapter(app)