适配器
适配器
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)