NestJs WebSocket与Vue WebSocket

一、NestJs WebSocket

  1. 安装依赖
    npm i --save @nestjs/websockets @nestjs/platform-socket.io
    npm i ws
  2. 新建ws.gateway.ts文件
import {
  ConnectedSocket,
  MessageBody,
  SubscribeMessage,
  WebSocketGateway,
} from '@nestjs/websockets';
import * as WebSocket from 'ws';

@WebSocketGateway(17030)
export class WsStartGateway {
  @SubscribeMessage('hello')
  hello(@MessageBody() data: string): string {
    return data;
  }

  @SubscribeMessage('hello2')
  hello2(
    @MessageBody() data: string,
    @ConnectedSocket() client: WebSocket,
  ): string {
    console.log('收到消息 client:', client);
    // client.send(JSON.stringify({ event: 'tmp', data: '这里是个临时信息' }));
    return data;
  }
}

  1. 把WsStartGateway放到AppModule的providers里
import { WsStartGateway } from './component/ws/ws.gateway';
@Module({
  providers: [AppService, WsStartGateway],
}
  1. 自定义适配器(WebSocketAdapter) ,新建一个ws.adapter.ts文件
import * as WebSocket from 'ws';
import { WebSocketAdapter, INestApplicationContext } from '@nestjs/common';
import { MessageMappingProperties } from '@nestjs/websockets';
import { Observable, fromEvent, EMPTY } from 'rxjs';
import { mergeMap, filter } from 'rxjs/operators';

export class WsAdapter implements WebSocketAdapter {
  constructor(private app: INestApplicationContext) {}

  create(port: number, options: any = {}): any {
    console.log('ws create');
    return new WebSocket.Server({ port, ...options });
  }

  bindClientConnect(server, callback: Function) {
    console.log('ws bindClientConnect, server:\n', server);
    server.on('connection', callback);
  }

  bindMessageHandlers(
    client: WebSocket,
    handlers: MessageMappingProperties[],
    process: (data: any) => Observable<any>,
  ) {
    console.log('[waAdapter]有新的连接进来');
    fromEvent(client, 'message')
      .pipe(
        mergeMap((data) =>
          this.bindMessageHandler(client, data, handlers, process),
        ),
        filter((result) => result),
      )
      .subscribe((response) => client.send(JSON.stringify(response)));
  }

  bindMessageHandler(
    client: WebSocket,
    buffer,
    handlers: MessageMappingProperties[],
    process: (data: any) => Observable<any>,
  ): Observable<any> {
    let message = null;
    try {
      message = JSON.parse(buffer.data);
      console.log(message);
    } catch (error) {
      console.log('ws解析json出错', error);
      return EMPTY;
    }

    const messageHandler = handlers.find((handler) => {
      return handler.message === message.event;
    });
    if (!messageHandler) {
      return EMPTY;
    }
    return process(messageHandler.callback(message.data));
  }

  close(server) {
    console.log('ws server close');
    server.close();
  }
}

  1. 在main.ts里使用这个适配器
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { WsAdapter } from './ws/ws.adapter';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  app.useWebSocketAdapter(new WsAdapter(app)); // 使用我们的适配器
  await app.listen(3001);
}
bootstrap();

  1. ws://localhost:17030

二、Vue WebSocket

  1. socket.js
import { Message } from 'hui';

class MessageSocket {
  constructor () {
    this.ws = null
    this.socketStatus = false
  }

  connect() {
    this.ws = new WebSocket('ws://localhost:17030')
    this.ws.onopen = this.onopen.bind(this)
    this.ws.onmessage = this.onmessage.bind(this)
    this.ws.onclose = this.onclose.bind(this)
    this.ws.onerror = this.onerror.bind(this)
  }

  onopen() {
    this.socketStatus = true
    console.log('websocket连接成功!', this.ws)
  }

  onmessage(e) {
    console.log('xia', e)
    console.log(JSON.parse(e.data))
  }

  onclose() {
    this.socketStatus = false
    console.log('websocket连接关闭.')
  }

  onerror() {
    console.log(e)
    this.socketStatus = false
    Message.error({
      showClose: true,
      message: 'websocket连接失败',
      duration: 0
    })
  }

  send(message) {
    if(this.ws && this.socketStatus) {
      this.ws.send(JSON.stringify(message))
      console.log('发送成功', JSON.stringify(message))
    }
  }
}

const messageSocket = new MessageSocket()

export default messageSocket
  1. 发送消息
import messageSocket from './socket'
messageSocket.connect()
messageSocket.send({
  event: 'hello',
  data: 'xia xin'
})

你可能感兴趣的:(websocket,vue.js,node.js)