websocket 指定對象發送

我知道 Socket 可以指定IP端口去发送消息给客户端,如果我在 WebSocket 想要指定发送消息给某个连接中的Client,如何实现呢?

WebSocket 中,可以通过存储连接的方式来实现向特定客户端发送消息。

当客户端连接到 WebSocket 时,服务器会为每个客户端创建一个唯一的标识符,称为“连接 ID”或“会话 ID”。这个连接 ID 可以用于标识客户端和存储与该客户端相关的信息,例如其订阅的频道等。

有多种方法可以将连接 ID 存储在服务器端。以下是其中两种常见的方法:

使用 Map 数据结构
使用 Map 数据结构可以将连接 ID 映射到客户端对象上。在客户端连接到 WebSocket 并建立连接时,我们可以将其连接 ID 和客户端对象存储到一个 Map 中。当需要向特定客户端发送消息时,只需要从 Map 中获取对应的客户端对象即可。

以下是使用 Map 存储连接 ID 的示例代码:

javascript
const WebSocket = require('ws')

const wss = new WebSocket.Server({ port: 8080 })

// 存储连接 ID 和客户端对象的 Map
const clients = new Map()

wss.on('connection', (ws) => {
  // 生成连接 ID
  const connId = uuid.v4()

  // 存储连接 ID 和客户端对象
  clients.set(connId, ws)

  ws.on('message', (message) => {
    console.log(`Received message from client ${connId}: ${message}`)
  })

  ws.on('close', () => {
    // 移除连接 ID 和客户端对象
    clients.delete(connId)
  })
})

function sendToClient(connId, message) {
  // 从 Map 中获取客户端对象
  const client = clients.get(connId)

  if (client && client.readyState === WebSocket.OPEN) {
    client.send(message)
  }
}
在这个示例中,我们使用了一个 Map 对象 clients 来存储连接 ID 和客户端对象的映射关系。当客户端连接到 WebSocket 并建立连接时,我们生成一个唯一的连接 ID,并将其与客户端对象存储在 Map 中。当需要向特定客户端发送消息时,我们只需要从 Map 中获取对应的客户端对象并调用它的 send 方法即可。

在客户端对象上添加属性
另一种方法是在客户端对象上添加一个属性来存储连接 ID。在客户端连接到 WebSocket 并建立连接时,我们可以将其连接 ID 存储在客户端对象的属性中。当需要向特定客户端发送消息时,只需要遍历所有客户端对象,找到具有指定连接 ID 的客户端对象并调用其 send 方法即可。

以下是在客户端对象上添加属性来存储连接 ID 的示例代码:

javascript
const WebSocket = require('ws')

const wss = new WebSocket.Server({ port: 8080 })

wss.on('connection', (ws) => {
  // 生成连接 ID
  const connId = uuid.v4()

  // 将连接 ID 存储在客户端对象上
  ws.connId = connId

  ws.on('message', (message) => {
    console.log(`Received message from client ${ws.connId}: ${message}`)
  })

  ws.on('close', () => {
    // 移除连接 ID
    delete ws.connId
  })
})

function sendToClient(connId, message) {
  wss.clients.forEach((client) => {
    if (client.connId === connId && client.readyState === WebSocket.OPEN) {
      client.send(message)
    }
  })
}
在这个示例中,我们将连接 ID 存储在客户端对象的 connId 属性上。当需要向特定客户端发送消息时,我们遍历所有客户端对象,找到具有指定连接 ID 的客户端对象并调用其 send 方法即可。

  • 你可以参考下这个问题的回答, 看看是否对你有帮助, 链接: https://ask.csdn.net/questions/917895
  • 我还给你找了一篇非常好的博客,你可以看看是否有帮助,链接:WebSocket 获取客户端的IP
  • 除此之外, 这篇博客: 为什么需要 WebSocket协议?中的 💰WebSocket中的常用注解有哪些? 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:
  • @ServerEndpoint :类似与servlet中的 RequestMapping
    @OnOpen:类似与servlet中的 init()初始化
    @OnClose:类似与servlet中的destroy() 销毁
    @OnMessage:类似于servlet中的service请求 (意思就是发送数据的方式 @doPost()/ @doGet() 组合)

  • 您还可以看一下 谭亮老师的websocket实现斗鱼弹幕系统课程中的 服务器的消息如何发给客户端小节, 巩固相关知识点
  • 以下回答由chatgpt基于相关博客总结生成:

    WebSocket 中可以通过获取连接实例来发送消息给某个 Client。具体实现步骤如下:

    1. 在服务端保存 WebSocket 连接实例,可以将连接实例存储在数组、字典或其他数据结构中,方便后续根据需要获取相应的连接实例。

    2. 在服务端监听连接实例的消息事件,可以在回调函数中编写处理逻辑,比如根据客户端传输的消息数据来选择要发送给哪个 Client。

    3. 在服务端向指定的连接实例发送数据,可以通过获取要发送的连接实例来实现。例如,可以通过数组下标、客户端 ID 或其他标识符来获取连接实例,然后使用 send 方法发送数据。

    以下是具体实现的伪代码:

    // Step 1: Save websocket connection instances in an array

    var connections = [];

    ws.on('connection', function(connection) { connections.push(connection); });

    // Step 2: Handle incoming messages and send responses

    ws.on('message', function(message) { // Parse message data to extract target client identifier var targetId = message.targetId; var payload = message.payload;

    // Find the target connection based on identifier var targetConnection = connections.find(function(connection) { return connection.clientId === targetId; });

    // Send the payload to the target client targetConnection.send(payload); });

    // Step 3: Send data to a specific websocket client

    var targetConnection = connections[targetIndex]; targetConnection.send(data);

    请注意,在实际项目中,代码实现可能会更加复杂。例如,您可能需要使用数据库来存储连接实例和相关数据,并且需要处理来自用户的错误数据或防范恶意攻击。因此,上述伪代码仅作为 WebSocket 实现的参考。