如何将NestJS用作WebSocket客户端?我想使用NestJS作为客户端连接到远程WebSocket服务器,但我在框架中没有找到有关此实现的任何信息。
kqqjbcuj1#
由于Nestjs只是Nodejs的一个框架,所以你需要找到一个支持WebSocket的NPM包。例如,我使用ws和@types/ws类型定义,并创建一个WebSocket客户端作为Nestjs服务类:
ws
@types/ws
// socket-client.ts import { Injectable } from "@nestjs/common"; import * as WebSocket from "ws"; @Injectable() export class WSService { // wss://echo.websocket.org is a test websocket server private ws = new WebSocket("wss://echo.websocket.org"); constructor() { this.ws.on("open", () => { this.ws.send(Math.random()) }); this.ws.on("message", function(message) { console.log(message); }); } send(data: any) { this.ws.send(data); } onMessage(handler: Function) { // ... } // ... } // app.module.ts import { Module } from "@nestjs/common"; import { WSService } from "./socket-client"; @Module({ providers: [WSService] }) export class AppModule {}
aoyhnmkz2#
我试着用另一种方法。我用socket.io-client写了一个适配器。然后通过方法useWebSocketAdapter在 Bootstrap 中使用此适配器。之后,我可以像处理套接字服务器一样在网关中编写处理WebSocket事件(使用装饰器@SubscribeMessage)我的适配器文件
socket.io-client
useWebSocketAdapter
@SubscribeMessage
import { WebSocketAdapter, INestApplicationContext } from '@nestjs/common'; import { MessageMappingProperties } from '@nestjs/websockets' import * as SocketIoClient from 'socket.io-client'; import { isFunction, isNil } from '@nestjs/common/utils/shared.utils'; import { fromEvent, Observable } from 'rxjs'; import { filter, first, map, mergeMap, share, takeUntil } from 'rxjs/operators'; export class IoClientAdapter implements WebSocketAdapter { private io; constructor(private app: INestApplicationContext) { } create(port: number, options?: SocketIOClient.ConnectOpts) { const client = SocketIoClient("http://localhost:3000" , options || {}) this.io = client; return client; } bindClientConnect(server: SocketIOClient.Socket, callback: Function) { this.io.on('connect', callback); } bindClientDisconnect(client: SocketIOClient.Socket, callback: Function) { console.log("it disconnect") //client.on('disconnect', callback); } public bindMessageHandlers( client: any, handlers: MessageMappingProperties[], transform: (data: any) => Observable<any>, ) { const disconnect$ = fromEvent(this.io, 'disconnect').pipe( share(), first(), ); handlers.forEach(({ message, callback }) => { const source$ = fromEvent(this.io, message).pipe( mergeMap((payload: any) => { const { data, ack } = this.mapPayload(payload); return transform(callback(data, ack)).pipe( filter((response: any) => !isNil(response)), map((response: any) => [response, ack]), ); }), takeUntil(disconnect$), ); source$.subscribe(([response, ack]) => { if (response.event) { return client.emit(response.event, response.data); } isFunction(ack) && ack(response); }); }); } public mapPayload(payload: any): { data: any; ack?: Function } { if (!Array.isArray(payload)) { return { data: payload }; } const lastElement = payload[payload.length - 1]; const isAck = isFunction(lastElement); if (isAck) { const size = payload.length - 1; return { data: size === 1 ? payload[0] : payload.slice(0, size), ack: lastElement, }; } return { data: payload }; } close(server: SocketIOClient.Socket) { this.io.close() } }
main.js
import { NestFactory } from '@nestjs/core'; import { AppModule } from './app.module'; import {IoClientAdapter} from './adapters/ioclient.adapter' async function bootstrap() { const app = await NestFactory.create(AppModule); app.useWebSocketAdapter(new IoClientAdapter(app)) await app.listen(3006); console.log(`Application is running on: ${await app.getUrl()}`); } bootstrap();
则网关
import { MessageBody, SubscribeMessage, WebSocketGateway, WebSocketServer, WsResponse, } from '@nestjs/websockets'; import { from, Observable } from 'rxjs'; import { map } from 'rxjs/operators'; import { Server } from 'socket.io'; @WebSocketGateway() export class EventsGateway { @WebSocketServer() server: Server; @SubscribeMessage('hello') async identity(@MessageBody() data: number): Promise<number> { console.log(data) return data; } }
这是一个骗局,但看起来很酷.消息处理程序可以写得更像nestjs风格。
2条答案
按热度按时间kqqjbcuj1#
由于Nestjs只是Nodejs的一个框架,所以你需要找到一个支持WebSocket的NPM包。例如,我使用
ws
和@types/ws
类型定义,并创建一个WebSocket客户端作为Nestjs服务类:aoyhnmkz2#
我试着用另一种方法。我用
socket.io-client
写了一个适配器。然后通过方法useWebSocketAdapter
在 Bootstrap 中使用此适配器。之后,我可以像处理套接字服务器一样在网关中编写处理WebSocket事件(使用装饰器@SubscribeMessage
)我的适配器文件
main.js
则网关
这是一个骗局,但看起来很酷.消息处理程序可以写得更像nestjs风格。