非常教程

Nest参考手册

WEBSOCKETS

适配器

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));

WEBSOCKETS相关

Nest

Nest 是一个用于构建高效,可扩展的 Node.js 服务器端应用程序的框架

Nest目录

1.介绍
2.常见问题
3.CLI
4.方法
5.执行上下文
6.微服务
7.WEBSOCKETS
8.GRAPHQL
9.技术
10.基本内容
11.迁移指南