如何忽略通过HTTP进行更改的客户端的websocket事件?



我们有一个React应用程序,它使用REST来获取和更新数据,并使用Websocket来接收更改通知。

想象我们有一个集合/用户

  1. user1 调用 http 方法 POST/users 来创建新用户
  2. user1 收到积极的 http 响应,并且创建的用户被添加到 UI 列表中。
  3. user1 还收到 Websocket 通知"user:created",并再次尝试将新项添加到 UI 列表。

因此,由于 HTTP 响应和 WS 事件,进行调用的用户应处理结果两次。这就是我试图解决的问题。

几种可能的解决方案: 1. 跳过调用 POST/users 的用户的 WS 事件。问题他可能有几个打开的浏览器选项卡。所有这些都不会更新。 2. 不处理 HTTP 响应,只处理 WS 事件。

有人遇到过这样的问题吗?还有哪些其他解决方案可用?

您基本上已经指出了最佳解决方案 (2.(,但这里有一些选项

  1. 不要使用来自 POST 的响应,而是等待"user:created"事件,该事件将更新所有订阅客户端(包括启动 POST 的客户端(的列表 -建议的方法
  2. 使用您当前的实现,但您的 POST 和"user:created"事件应该共享某种标识符,它们与请求的其余部分一起返回,客户端可以使用该标识符来确定他是否已经获得了该信息 - 例如"user:created:{userId}"。然后,只有内存中没有"user:created:{userId}"的客户端才会使用 WS 事件数据。- 不推荐
  3. 跳过启动 POST 的用户的 WS 事件 -
  4. 问题是如果特定用户连接了多个客户端(选项卡、浏览器 + 移动设备等( - 使用这种方法,您必须跳过启动 POST 请求的客户端(套接字术语中的 connectionId(的 WS 事件(不是用户!因此,如果用户有 10 个连接,您将向 9 个连接发送"user:created"事件,除了发起请求的连接 + 应接收该事件的所有其他连接 - 不建议这样做,因为它会使您的后端复杂化很多。

在我看来,最简单和最干净的方法是忽略 POST 响应并等待该 WS 事件 - 因为这些是套接字,您不应该有任何 UI 问题或延迟。

如果已添加用户的客户端发出事件,则使用

// sending to all clients except sender
socket.broadcast.emit('broadcast', 'hello friends!');

这不会向客户端发出事件,您可以在 react 应用程序中使用逻辑来侦听套接字事件以及 http 请求的响应。 这将防止重复或错误数据。

如果为同一客户端打开了多个选项卡,则发起 http 请求的客户端选项卡将使用 http 响应更新状态列表,所有其他用户的选项卡或其他用户将收到套接字事件。

一种方法是在请求中添加"幂等计数器"字段。基本上它只是一个数字,每个请求都会递增,并存储在前端。后端需要为每个成功的请求使用相同的计数器进行应答。

您的处理逻辑如下所示:

function onUserAdded(user, counter) {
if(current_counter < counter) { 
console.log("User added");
current_counter++;
} else {
console.log("User not added");
}
}
  • current_counter=0
  • 调用POST /users,带有counter = current_counter + 1,使用counter=1->User added获得响应
  • 使用counter=1->User not added获取 websocket 通知