如何有条件地发送WebSocket消息?

huangapple go评论95阅读模式
英文:

How to send a websocket message conditionally?

问题

我正在使用JavaScript中的ws包和expressjs作为我的服务器。

我正在为我的作品集构建一个聊天应用程序,最初的想法是让客户端告诉服务器用户在哪些聊天中(订阅了哪些),然后将它们存储在subscriptions数组中。

  for (let i = 0; i < subscriptions.length; i++) {
        
          wss.clients.forEach((client) => {
            if (json.body.chatId === subscriptions[0][i]){
              client.send(message)
          }
        })
      }

这是我最初的方法,但消息会发送给每个连接的客户端,这太糟糕了。

subscriptions对象只是一个包含用户所在聊天的ID的数组。

如何只向在聊天中的客户端发送消息呢?

英文:

I am using the ws package in javascript and expressjs for my server.

I am building a chat application for my portfolio and initially my idea was to have the client tell the server which chats the user was in (subscribed to) and store them in a subscriptions array.

  for (let i = 0; i &lt; subscriptions.length; i++) {
        
          wss.clients.forEach((client) =&gt; {
            if (json.body.chatId === subscriptions[0][i]){
              client.send(message)
          }
        })
      }

This is how I thought to approach it, but the message gets sent to EVERY connected client which is terrible.

The subscriptions object is just an array with the id's of chats the user is in.

How can I send the message only to clients that are in the chat?

答案1

得分: 1

首先,您需要维护每个客户端与其订阅的聊天ID之间的映射关系。您可以使用JavaScript中的Map来实现这一点,其中键是客户端对象,值是他们订阅的聊天ID数组:

const subscriptionsMap = new Map();

当客户端连接到WebSocket时,将他们的订阅信息存储在subscriptionsMap中。并且当客户端断开连接时,确保从映射中删除他们的订阅:

wss.on('connection', (client) => {
  // 处理客户端连接

  // 假设 `json.body.subscriptions` 包含客户端订阅的聊天ID数组
  subscriptionsMap.set(client, json.body.subscriptions);

  // 处理客户端断开连接
  client.on('close', () => {
    subscriptionsMap.delete(client);
    // 执行任何必要的清理操作
  });
});

现在,当您收到需要发送到特定聊天的消息时,遍历已连接的客户端,并仅将消息发送给那些订阅了相关聊天ID的客户端:

// 假设 `json.body.chatId` 包含消息的聊天ID
const chatId = json.body.chatId;

wss.clients.forEach((client) => {
  if (subscriptionsMap.has(client) && subscriptionsMap.get(client).includes(chatId)) {
    client.send(message);
  }
});
英文:

First, you need to maintain a mapping of each client to their subscribed chat IDs. You can use a JavaScript Map to achieve this, where the keys are the client objects and the values are arrays of chat IDs they are subscribed to:

const subscriptionsMap = new Map();

When a client connects to the WebSocket, store their subscription information in the subscriptionsMap. And when a client disconnects, make sure to remove their subscriptions from the map:

wss.on(&#39;connection&#39;, (client) =&gt; {
  // Handle client connection

  // Assume `json.body.subscriptions` contains the array of chat IDs the client is subscribed to
  subscriptionsMap.set(client, json.body.subscriptions);

  // Handle client disconnection
  client.on(&#39;close&#39;, () =&gt; {
    subscriptionsMap.delete(client);
    // Perform any necessary cleanup
  });
});

Now, when you receive a message that needs to be sent to clients in specific chats, iterate through the connected clients and send the message only to those who are subscribed to the relevant chat IDs:

// Assuming `json.body.chatId` contains the chat ID for the message
const chatId = json.body.chatId;

wss.clients.forEach((client) =&gt; {
  if (subscriptionsMap.has(client) &amp;&amp; subscriptionsMap.get(client).includes(chatId)) {
    client.send(message);
  }
});

huangapple
  • 本文由 发表于 2023年7月27日 19:09:28
  • 转载请务必保留本文链接:https://go.coder-hub.com/76779150.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定