Cometd:在线用户管理的多个选项卡创建错误的在线状态

Cometd : Multiple tabs for online-users management creating false online-status

我正在开发一个基于 Spring-MVC 的网络应用程序,它使用 Cometd 进行聊天。为了实时管理哪个用户在线,我们在用户在线时发送通知。因此,当 window 关闭时,不会出现通知,并且在 30 秒后确定用户离线或无法访问。

现在当用户使用多个浏览器时会出现问题。让我们现在保留它 2。因此,10 分钟后,我们将用户状态设置为 'Away from Keyboard'(AFK)。但是如果用户在一个浏览器中在线,那么我们会得到一个闪烁状态,由于 'Idle Mode' 中的浏览器,我们会得到一个闪烁状态,我们得到一个 AFK,并且从活动机器我们得到一个 'Available'状态。

我们如何解决这个问题?任何想法,建议。我想到了使用布尔标志,并与 IP 地址结合使用,在覆盖通知之前将检查它,但它有过时通知的问题。

这是我的代码,用于向所有听众(用户的朋友)发送在线通知。

代码:

 @Listener(value = "/service/online")
    public void OnlineNotifications(ServerSession remote, ServerMessage.Mutable message) {
        Person sender = this.personService.getCurrentlyAuthenticatedUser();
        Map<String, Object> input = message.getDataAsMap();
        String onlineStatus = (String) input.get("status");
        Map<String, Object> output = new HashMap<>();
        output.put("status", onlineStatus);
        output.put("id", sender.getId());
        ServerChannel serverChannel = bayeux.createChannelIfAbsent("/online/" + sender.getId()).getReference();
        serverChannel.setPersistent(true);
        serverChannel.publish(serverSession, output);
    }

欢迎任何想法。非常感谢。 :-)

您的应用程序可以轻松地将多个设备与同一个 userName 相关联。 您可以从 SecurityPolicy 执行此操作,只需将 userName 字符串与 List<ServerSession> 或更适合您的情况的任何数据结构相关联即可。

您在特定 userName 的在线状态因此是该特定 userName 的所有 ServerSession 的函数。 因此,它是从 userName 到在线状态列表的映射。

如果您想象用户 bob 从两个浏览器登录,其在线状态的映射可以是:

"bob" -> ["afk", "online"]

要计算 bob 的在线状态,您只需 运行 通过每个 ServerSession 的所有在线状态,如果至少有一个 online 则它在线,如果都是afk那么就是远离键盘,以此类推。

您可以通过多种方式实现此逻辑(例如,将在线状态存储为 ServerSession 属性、使用不同的数据结构、缓存每个用户的在线状态等),但您得到想法。

每当您从一个 ServerSession 获得在线状态更改时,您更新服务器端数据结构,然后重新计算该用户的所有 ServerSession 的在线状态,即您发送给其他用户的内容。