Cometd:用于在线用户管理的多个选项卡,可创建虚假的在线状态

时间:2015-07-20 08:52:01

标签: java spring comet cometd

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

现在当用户在多个浏览器上时会出现问题。让我们现在保持2。因此,在10分钟后,我们将用户状态设置为“远离键盘”(AFK)。但是如果用户在一个浏览器中联机,那么我们将获得一个闪烁的状态,因为浏览器处于“空闲模式”状态几秒钟,我们得到一个AFK,并且从活动机器我们得到一个& #39;可用'状态。

我们如何解决这个问题?任何想法,建议。我想过使用一个布尔标志,并与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);
    }

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

1 个答案:

答案 0 :(得分:1)

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

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

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

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

要计算bob的在线状态,您只需浏览每个ServerSession的所有在线状态,如果至少有一个online,那么它就在线,如果全部是{{} 1}}然后它远离键盘,依此类推。

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

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