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
的在线状态,即您发送给其他用户的内容。
我正在开发一个基于 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
的在线状态,即您发送给其他用户的内容。