【发布时间】:2022-02-13 19:42:48
【问题描述】:
我正在创建一个聊天应用程序,其中一个细节是“确认”至关重要。我会明白这意味着什么。我正在尝试找出最好的交换协议是什么。
场景: Alice 向 Bob 发送一条消息。 Bob 离线,因此消息存储在服务器上。 Bob 通过 WebSocket 连接连接到服务器。服务器向他发送在他不在时发送给他的消息。这就是问题出现的地方。可用于我的应用程序生态系统(特别是 Node.js、Nest.js)的 WS API 没有可以等待此消息发送的模式。 mechanism 似乎只是火与忘记。如果负载非常大并且在发送消息时连接断开怎么办?
现在,我知道 socket.io 有 support for acknowledgements。但是从我读到的内容来看,socket.io 有一些开销,因此性能不如最佳。现在,这种性能是否是我可以说需要的东西是另一个问题,但我只是想弄清楚如何保证消息已经到达另一端。这意味着客户端-服务器和服务器-客户端方向。我怎样才能await呢?我知道一种方法是将唯一 ID 附加到套接字事件,并让另一方向您发送确认它已收到它。如果我没记错的话,socket.io 就是这样做的。
但我的问题是如何保证确认消息已成功发送?那么我的“ack”需要一个“ack”等等,所以我总是需要一个确认,所以我不知道它是如何工作的。
我想到的选项是使用两个 REST 端点来处理 send 和 receive(或下载)消息。您在发送时发送,但是当您接收到有消息供您下载的 ping 时,您会收到。现在这可以通过 WebSocket 连接来完成,在该连接中,服务器通知客户端一条新消息,然后客户端可以调用此 receive 端点。此 ping 也可以通过更受管理的解决方案(如 FCM)来完成。这种方法的优点是双重的:
- 首先,我有 REST 接口可以使用,它更实用
- 我可以使用请求-响应模式,所以我有一个理论上的保证,如果我得到响应,事情就会到达
现在这种方法的问题是,如果我没记错的话,每次我想发送或接收消息时打开一个新的 HTTP 连接都会产生很多开销:
-
我必须等待初始请求时间才能到达服务器,然后才能真正等待服务器响应消息。对于纯 WebSockets 案例,理论上我会在那里等待响应等效部分(?)
-
这也会浪费带宽。
还有一个问题,我在哪里可以找到哪些客户端实际上会重用现有的 HTTP 连接(如 WebSocket 连接)(如果可用)而不创建新的连接?所有客户都这样做吗?只有浏览器吗?应用程序呢?是操作系统级别的吗?
所以最后一个问题是我如何解决这个“确认”问题而不浪费时间和带宽?我的任何结论/问题是否错误或不知情,我是否遗漏了什么?
注意事项:
- 服务器是Node.js,客户端是Flutter
- 我知道 WAMP 子协议,但对于我的生态系统而言,它没有非常可靠的实现
【问题讨论】:
标签: node.js flutter dart websocket