处理连接到不同副本的WebSocket连接

问题描述

后端在具有N个副本的kubernetes上运行。 前端用户(浏览器)监听websocket的实时消息。

由于后端具有N个副本,因此每个浏览器都连接到不同的副本。 假设有一个用户A B C,都已打开2个标签,即A1 A2 B1 B2 C1 C2。

后端副本1可以容纳A1 B1的Web套接字连接 后端副本2可以容纳A2 B2 C1 C2的Web套接字连接

(如果我到这里都错了,请纠正我。但是,据我所知并经过测试,这是如何工作的)

要向所有用户广播消息,我将所需消息发布到RabbiqMQ。我正在使用Fanout交换,因此每个后端副本都将使用该通知。然后,每个服务器将消息发送给它拥有的所有用户(连接)。

一个问题,这是正确的做法还是有更好的办法?拥有单独的服务器仅用于处理WS连接会更明智吗?

现在,我需要一个解决方案来检测用户是否关闭了所有选项卡(离开了应用程序),并在db中更新了该用户。我最初的想法是检测websocket断开事件,检查用户是否还有活动连接。但是这样做似乎非常复杂,因为用户可能已经打开了3个标签,每个标签都连接到不同的后端服务器。

有人知道如何实现吗?

解决方法

要跟踪谁已连接以及谁关闭了所有选项卡,您需要有一个类似 DB 的实例。您需要做的就是在有人连接或断开连接时向该实例发布一个事件。

一个简单的实现是有一个字典,其中一个用户标识符作为键,会话数作为一个值。

当用户连接到 websocket 时,您发布一个 onSavedInstace 事件以增加会话数。

当用户断开连接时,您发布一个 connected 事件,该事件会减少会话数并返回剩余会话数,如果该数等于 0,则返回一个布尔值。然后您可以执行任何您需要的操作清理他的会话。

注意:如果有多个线程接收事件,则需要使写入操作同步。一个好的解决方案是使用支持 ACID 的 SQL 数据库。

如果您需要更多控制,可以扩展解决方案以拥有发布订阅架构。其中连接是双向的,而不是上面的单向方法。这样,如果有人在另一个选项卡中连接,您可以与第一个选项卡交互并根据您的需要显示消息或断开连接。