NestJS WebSocket 广播事件到客户端

12

我无法通过websocket从NestJS服务器向客户端发送数据。 没有发出任何内容。

我的用例:

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

我的技术栈:

  • NestJS服务器和websocket
  • 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:

应该翻译为:

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(...) 吗? - Chau Tran
是的,没有成功。但我想我刚刚找到了答案:我必须使用c.send()而不是c.emit()!此外,client.id不起作用:我只需要比较socket的实例。我正在进展中,如果一切完全正常,我将发布解决方案代码。 - user2650606
这很奇怪,因为我已经使用了 this.server.emit(..) 如果我想向所有连接的客户端发出信号,而且它运行良好。 - Chau Tran
3个回答

13

如前面的评论所提到的,c.send() 与以下代码片段良好配合:

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

5

使用 socket.io,我们可以使用 socket.broadcast.emit() 么?

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

3

我尝试使用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" }]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接