java通过Websocket在Spring框架中实时检测离线和在线客户端
我正在构建一个类似slack的应用程序。我有很多客户在网络和手机上运行。它们通过Stomp
连接到websocket。我想实时检测哪个用户在线和离线Websocket
服务器正在spring framework
上运行。
spring接受如下请求。我将heartbeat
{outgoing
值设置为20000 ms
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
private List<StompPrincipal> onlineUsers = new ArrayList<>();
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/ws")
.setAllowedOrigins("*")
.setHandshakeHandler(new CustomHandshakeHandler())
.withSockJS();
}
@Override
public void configureMessageBroker(MessageBrokerRegistry config) {
config.setApplicationDestinationPrefixes("/ws");
config.enableSimpleBroker("/ws")
.setTaskScheduler(new DefaultManagedTaskScheduler())
.setHeartbeatValue(new long[]{20000,20000});
}
}
为了确定哪些用户请求Websocket
,我添加了一个握手处理程序,如下所示
class CustomHandshakeHandler extends DefaultHandshakeHandler {
@Override
protected Principal determineUser(ServerHttpRequest request, WebSocketHandler wsHandler,
Map<String, Object> attributes) {
String username=(String)attributes.get("name");
StompPrincipal user = new StompPrincipal(username)
onlineUsers.add(user);
return user;
}
}
class StompPrincipal implements Principal {
String name;
StompPrincipal(String name) {
this.name = name;
}
@Override
public String getName() {
return name;
}
}
正如上面的代码,我可以看到用户在请求websocket server
之后添加了onlineUser
。
但问题是,我无法确定用户在线后是否离线。你能建议我确定一下吗。
通过这种方式确定在线和离线用户也是最佳实践吗?如果没有,等待您的建议。现在非常感谢
# 1 楼答案
这在规范第节
中有描述 20.4.12监听应用程序上下文事件并拦截消息
https://docs.spring.io/spring-framework/docs/4.1.0.RC2/spring-framework-reference/html/websocket.html#websocket-stomp-appplication-context-events
SessionConnectedEvent
— 在SessionConnect事件后不久发布,此时代理已发送STOMP连接帧以响应CONNECT。在这一点上,跺脚会议可以被认为是完全建立起来的SessionDisconnectEvent
— 在跺脚会话结束时发布。断开连接可能是从客户端发送的,也可能是在WebSocket会话关闭时自动生成的。在某些情况下,此事件可能会在每个会话中发布多次。组件对于多个断开连接事件应该是幂等的如果需要,可以将在线用户存储在缓存中,并在用户来去时通过websocket将相关用户的在线状态流式传输到客户端
# 2 楼答案
使用会话Id检测用户
SocketJS
弹簧靴
}
# 3 楼答案
经过更多的搜索,我找到了一个描述为here的解决方案。我实现了
ApplicationListener<SessionDisconnectEvent>
并重写了下面的方法通过这种方式,我可以捕捉到哪个用户断开了websocket连接。 我仍在等待你的最佳实践建议