【问题标题】:NestJS websocket Broadcast event to clientsNestJS websocket 向客户端广播事件
【发布时间】:2019-05-05 16:34:27
【问题描述】:

我无法通过 websocket 从服务器 NestJS 向客户端发送数据。什么都没有发出。

我的用例:

  • 多个客户端通过 websocket 连接到服务器
  • 客户端通过 websocket 向服务器发送消息
  • 服务器向所有客户端广播消息

我的堆栈:

  • 带有 websocket 的 NestJS 服务器
  • Angular 客户端和其他(如用于测试 websocket 的 chrome 扩展)

我的代码:

simple-web-socket.gateway.ts:

import { SubscribeMessage, WebSocketGateway, WsResponse, WebSocketServer, OnGatewayConnection, OnGatewayDisconnect, OnGatewayInit } from '@nestjs/websockets';

@WebSocketGateway({ port: 9995, transports: ['websocket'] })
export class SimpleWebSocketGateway implements OnGatewayConnection, OnGatewayDisconnect, OnGatewayInit {

  @WebSocketServer() private server: any;
  wsClients=[];
  afterInit() {
    this.server.emit('testing', { do: 'stuff' });
  }

  handleConnection(client: any) {
    this.wsClients.push(client);
  }

  handleDisconnect(client) {
    for (let i = 0; i < this.wsClients.length; i++) {
      if (this.wsClients[i].id === client.id) {
        this.wsClients.splice(i, 1);
        break;
      }
    }
    this.broadcast('disconnect',{});
  }
  private broadcast(event, message: any) {
    const broadCastMessage = JSON.stringify(message);
    for (let c of this.wsClients) {
      c.emit(event, broadCastMessage);
    }
  }

  @SubscribeMessage('my-event')
  onChgEvent(client: any, payload: any) {
    this.broadcast('my-event',payload);
  }
}

main.ts:

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { WsAdapter } from '@nestjs/websockets';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  app.useWebSocketAdapter(new WsAdapter());
  await app.listen(3000);
}
bootstrap();

app.module.ts:

import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { SimpleWebSocketGateway } from 'simple-web-socket/simple-web-socket.gateway';

@Module({
  imports: [],
  controllers: [AppController],
  providers: [AppService, SimpleWebSocketGateway],
})
export class AppModule {}

其他信息:

客户端发射(使用代码行 c.emit(event, broadCastMessage);)返回 false。

我怀疑框架中有错误,因为我的用法很简单。但如果我做错了什么,我想在这里与社区再次确认。

【问题讨论】:

  • 你试过this.server.emit(...)吗?
  • 是的,没有成功。但我想我只是找到了答案:我必须使用 c.send() 而不是 c.emit() ! client.id 也不起作用:我只需要比较套接字的实例。我正在处理它,如果完全没问题,我会发布解决代码。
  • 这很奇怪,因为如果我想向所有连接的客户端发出信号,我已经使用了this.server.emit(..),它工作正常。

标签: websocket nestjs


【解决方案1】:

正如前面评论中提到的,c.send() 可以很好地与以下 sn-p 配合使用:

import { SubscribeMessage, WebSocketGateway, WsResponse, WebSocketServer, OnGatewayConnection, OnGatewayDisconnect, OnGatewayInit } from '@nestjs/websockets';

@WebSocketGateway({ port: 9995, transports: ['websocket'] })
export class SimpleWebSocketGateway implements OnGatewayConnection, OnGatewayDisconnect, OnGatewayInit {

  @WebSocketServer() private server: any;
  wsClients=[];
  afterInit() {
    this.server.emit('testing', { do: 'stuff' });
  }

  handleConnection(client: any) {
    this.wsClients.push(client);
  }

  handleDisconnect(client) {
    for (let i = 0; i < this.wsClients.length; i++) {
      if (this.wsClients[i] === client) {
        this.wsClients.splice(i, 1);
        break;
      }
    }
    this.broadcast('disconnect',{});
  }
  private broadcast(event, message: any) {
    const broadCastMessage = JSON.stringify(message);
    for (let c of this.wsClients) {
      c.send(event, broadCastMessage);
    }
  }

  @SubscribeMessage('my-event')
  onChgEvent(client: any, payload: any) {
    this.broadcast('my-event',payload);
  }
}

【讨论】:

    【解决方案2】:

    我尝试使用client.send() 向所有连接的客户端广播消息:

    broadcastMessage(event: string, payload: any) {
      for (const client of this.clients) {
        client.send(event, payload);
      }
    }
    
    testBroadcast() {
      this.broadcastMessage('msgInfo', { name: 'foo' });
    }
    

    发送的数据最终如下所示:

    ["message", "msgInfo", { "name": "foo" }]
    

    以上方法对我不起作用,所以我使用了client.emit(),它工作正常:

    broadcastMessage(event: string, payload: any) {
      for (const client of this.clients) {
        client.emit(event, payload);
      }
    }
    

    现在数据看起来像这样:

    ["msgInfo", { "name": "foo" }]
    

    【讨论】:

      【解决方案3】:

      通过 socket.io 我们可以使用socket.broadcast.emit()?:

      @SubscribeMessage('my-event')
      onChgEvent(
          @MessageBody() message: any,
          @ConnectedSocket() socket: Socket,
      ): void {
         socket.broadcast.emit('my-event', message);
      }
      

      【讨论】:

        猜你喜欢
        • 2015-07-04
        • 2011-03-10
        • 2019-12-01
        • 2018-11-14
        • 1970-01-01
        • 2016-12-02
        • 2021-02-05
        • 2019-04-01
        相关资源
        最近更新 更多