谁来解答一下ws怎么区分不同的用户?

比如使用nestjs写一个ws接口。页面A 和页面B 同时发送信息创建ws链接。这个时候怎么区分A B的接口 。如果接口发送了信息,AB都能收到吗?
下面是GPT的回答

import {
  SubscribeMessage,
  WebSocketGateway,
  OnGatewayConnection,
  OnGatewayDisconnect,
  WebSocketServer,
  MessageBody,
  ConnectedSocket,
} from '@nestjs/websockets';
import { Server, Socket } from 'socket.io';

// 装饰器 @WebSocketGateway() 用于定义一个 WebSocket 网关
@WebSocketGateway()
export class AppGateway implements OnGatewayConnection, OnGatewayDisconnect {
  // 使用 @WebSocketServer() 注入 Server 实例,允许我们通过它与客户端通信
  @WebSocketServer()
  server: Server;

  // 用于存储客户端连接的 Map,键为用户标识符,值为 Socket 实例
  private clients: Map<string, Socket> = new Map();

  // 当有新的客户端连接时触发
  handleConnection(client: Socket) {
    // 假设客户端在连接时通过查询参数传递了一个 `userId` 作为标识符
    const userId = client.handshake.query.userId as string;
    this.clients.set(userId, client);
    console.log(`Client connected: ${userId}`);
  }

  // 当客户端断开连接时触发
  handleDisconnect(client: Socket) {
    const userId = client.handshake.query.userId as string;
    this.clients.delete(userId);
    console.log(`Client disconnected: ${userId}`);
  }

  // 处理名为 'message' 的事件,此事件由客户端发起
  @SubscribeMessage('message')
  handleMessage(@MessageBody() data: string, @ConnectedSocket() client: Socket) {
    console.log(`Received message: ${data}`);
    
    // 向所有连接的客户端广播消息
    this.server.emit('message', data);

    // 可选:向特定客户端发送消息(这里使用一个特定的用户 ID)
    const targetClient = this.clients.get('specificUserId');
    if (targetClient) {
      targetClient.emit('message', data);
    }
  }
}
阅读 2.2k
2 个回答

每个连接都是一个用户这么分。伪代码

async handleConnection(client: Socket) {
const payload = this.authService.verify(
  client.handshake.headers.authorization,
);
const user = await this.usersService.findOne(payload.userId);

!user && client.disconnect();

this.connections[user.id] = client

}

给当前conn发送消息只有当前连接的用户能收到。给指定用户发消息就是 从this.connections里取出对应用户的id。

使用命名空间和房间来区分页面 A 和页面 B 的连接:

import { WebSocketGateway, WebSocketServer, SubscribeMessage, MessageBody, ConnectedSocket } from '@nestjs/websockets';
import { Server, Socket } from 'socket.io';

@WebSocketGateway({ namespace: '/namespaceA' })
export class NamespaceAGateway {
  @WebSocketServer() server: Server;

  @SubscribeMessage('joinRoom')
  handleJoinRoom(@MessageBody() room: string, @ConnectedSocket() client: Socket) {
    client.join(room);
  }

  @SubscribeMessage('message')
  handleMessage(@MessageBody() message: string, @ConnectedSocket() client: Socket) {
    this.server.to('roomA').emit('message', message);
  }
}

@WebSocketGateway({ namespace: '/namespaceB' })
export class NamespaceBGateway {
  @WebSocketServer() server: Server;

  @SubscribeMessage('joinRoom')
  handleJoinRoom(@MessageBody() room: string, @ConnectedSocket() client: Socket) {
    client.join(room);
  }

  @SubscribeMessage('message')
  handleMessage(@MessageBody() message: string, @ConnectedSocket() client: Socket) {
    this.server.to('roomB').emit('message', message);
  }
}
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题