在 NestJs 中使用 Socket IO 加入和发射到房间

Posted

技术标签:

【中文标题】在 NestJs 中使用 Socket IO 加入和发射到房间【英文标题】:Joining and emitting to rooms with Socket IO in NestJs 【发布时间】:2021-02-04 19:16:27 【问题描述】:

我正在尝试使用 socketio 在 Nestjs 中创建一个简单的房间,但无法掌握房间的概念。我想要的是客户端将一个 id 发送到一个通用端点,然后服务器将该套接字连接到一个特定的房间,然后开始从其他地方向那个房间发送消息。我目前拥有的是客户加入一个名为“会议”的活动,然后被发送一个假会议,但我不知道如何让多个客户加入同一个房间并一次发送相同的信息。

客户端 (html)

  <script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.3.1/socket.io.js"></script>
  <script>
    const url = 'http://localhost:4001';
    const socket = io(url); 
      socket.on('connect', function() 
        console.log('Connected');
        socket.emit('meeting',  roomId: '12345' );
      );
      socket.on('meeting', function(data) 
        console.log('you have joined the meeting: ', data);
      );
      socket.on('exception', function(data) 
        console.log('event', data);
      );
      socket.on('disconnect', function() 
        console.log('Disconnected');
      );
  </script>

服务器(NestJS):

@WebSocketGateway(4001)
export class PackGateway implements OnGatewayConnection 

  constructor(private otherService: OtherService) 

  @WebSocketServer()
  server: Server;

  handleConnection() 
    console.log('new connection!');
  

  @SubscribeMessage('meeting')
  joinUserToMeeting(@MessageBody() data: any, @ConnectedSocket() client: Socket): Observable<WsResponse<any>> 
    client.join(data.roomId, (err) => 
      if (err) 
        console.log('error ', err);
       else 
        console.log('client joined room: ' + data.roomId);
        this.server.to(data.meetingId).emit('a new challenger approaches');
      
    );
    return from(data.meetingId)
    .pipe(
      map(
        (res: any) => 
          return 
            event: 'meeting',
            data: data.meetingId
          
        
      )
    );
  

通过此设置,我的客户将连接到会议活动,加入他们在连接到会议活动时发送的 roomId,并返回他们加入的会议 ID。但是我错过了一个关键的事情:

    客户端实际上并没有打开服务器加入它的房间的连接。我是否需要在客户端代码中执行此操作才能开始与特定房间 ID 的连接?一旦我可以得到类似下面的东西,那么我认为我的客户端会在任何客户端加入时收到一条消息,因为在建立新连接时服务器会向该房间发出一条消息。
    <script>
    const url = 'http://localhost:4001';
    const socket = io(url);
    socket.on('connect', function () 
      console.log('Connected');
      socket.emit('meeting',  meetingId: '12345' );
    );
    socket.on('meeting', function (data) 
      console.log('you have joined the meeting: ', data);
      socket.in(data).on('roomIdEvent', function (data) 
        console.log('you got a new event specific to the meeting you joined');
        console.log('data');
      );
    );
    socket.on('exception', function (data) 
      console.log('event', data);
    );
    socket.on('disconnect', function () 
      console.log('Disconnected');
    );
  </script>

【问题讨论】:

【参考方案1】:

意识到当我的服务器向那个房间发出信号时,我没有正确构建消息:

所以

this.server.to(data.meetingId).emit('a new challenger approaches');

this.server.to(data.meetingId).emit('meeting', 'a new challenger approaches');

现在因为我的服务器已将客户端加入该房间,通过房间发送到会议允许我的客户端查看数据

【讨论】:

以上是关于在 NestJs 中使用 Socket IO 加入和发射到房间的主要内容,如果未能解决你的问题,请参考以下文章

NestJS + Socket.io:没有收到消息

如何使用 nestjs 和 socket.io 创建房间

Chrome v88+ 和 Nestjs 服务器上的 socket-io 连接出现 CORS 错误

NestJs Socket io 适配器:如果使用 false 调用 allowFunction,服务器不会将 CORS 标头添加到握手的响应中。错误或配置错误?

NESTJS 网关/Websocket - 如何通过 socket.emit 发送 jwt access_token

socket.io 加入/离开