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

喜夏-厌秋 提交于 2019-12-13 06:45:01

问题


I am working on a Spring-MVC based web-app which uses Cometd for chat purposes. For real-time management of which user is online, we are sending notifications when the user is online. So when window is closed, then notifications don't appear and after 30 seconds it is determined that the user is offline or not reachable.

Now the problem happens when user is over multiple browsers. Lets just keep it for 2 now. So, after 10 minutes we are setting user status to 'Away from Keyboard'(AFK). But if the user is online in one browser, then we are getting a blinking status, for few seconds because of the browser in 'Idle Mode', we get a AFK, and from the active machine we get an 'Available' status.

How can we solve this problem? Any ideas, suggestions. I thought of using a boolean flag, and couple with IP address, which will be checked before overwriting the notification, but it has a problem of stale notifications.

This is my code for sending out notifications for online to all listeners(Friends of user).

Code :

 @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);
    }

Any ideas are welcome. Thanks a lot. :-)


回答1:


Your application can easily associate multiple devices with the same userName. You can do this from your SecurityPolicy, just associate the userName string with a List<ServerSession> or whatever data structure fits better your case.

Your online state for a particular userName is therefore a function of all the ServerSessions of this particular userName. As such, it's a mapping from the userName to a list of online states.

If you imagine user bob logged in from two browsers, the mapping for its online status can be:

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

To compute the online status for bob you just run through all the online statuses for each ServerSession and if there is at least one online then it's online, if all are afk then it's away from the keyboard, and so on.

You can implement this logic in several ways (e.g. storing the online status as a ServerSession attribute, use a different data structure, cache the per-user online status, etc.), but you get the idea.

Whenever you get an online status change from one ServerSession, you update your server-side data structure, and then recompute the online status from all ServerSessions for that user, and that is what you send to the other users.



来源:https://stackoverflow.com/questions/31512310/cometd-multiple-tabs-for-online-users-management-creating-false-online-status

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!