use*_*547 21 spring stomp spring-boot spring-websocket
我已经搜索了很多并且无法找到这个:有没有办法让一个spring websocket stomp服务器可以根据sessionId断开客户端(或者真的基于任何东西)?
在我看来,一旦客户端连接到服务器,没有任何东西允许服务器断开客户端.
isa*_*huk 15
实际上使用一些解决方法,您可以实现您想要的.为此你应该这样做:
我已经创建了示例spring-boot项目,以展示我们如何从服务器端断开客户端会话:https: //github.com/isaranchuk/spring-websocket-disconnect
您还可以通过实现自定义来断开会话WebSocketHandlerDecorator:
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig<S extends ExpiringSession> extends AbstractSessionWebSocketMessageBrokerConfigurer<S> {
@Override
public void configureWebSocketTransport(final WebSocketTransportRegistration registration) {
registration.addDecoratorFactory(new WebSocketHandlerDecoratorFactory() {
@Override
public WebSocketHandler decorate(final WebSocketHandler handler) {
return new WebSocketHandlerDecorator(handler) {
@Override
public void afterConnectionEstablished(final WebSocketSession session) throws Exception {
session.close(CloseStatus.NOT_ACCEPTABLE);
super.afterConnectionEstablished(session);
}
};
}
});
super.configureWebSocketTransport(registration);
}
@Override
protected void configureStompEndpoints(final StompEndpointRegistry registry) {
registry.addEndpoint("/home")
.setHandshakeHandler(new DefaultHandshakeHandler(
new UndertowRequestUpgradeStrategy() // If you use undertow
// new JettyRequestUpgradeStrategy()
// new TomcatRequestUpgradeStrategy()
))
.withSockJS();
}
}
Run Code Online (Sandbox Code Playgroud)
我依靠 @D\xc3\xa1niel Kis 的想法,实现了 websocket 会话管理,其关键点是在类似 Singleton 的对象中为经过身份验证的用户存储 websocket 会话。
\n// WebSocketConfig.java\n\n@Configuration\n@EnableWebSocketMessageBroker\npublic class WebSocketConfig implements WebSocketMessageBrokerConfigurer {\n\n @Override\n public void configureWebSocketTransport(WebSocketTransportRegistration registration) {\n registration.addDecoratorFactory(new WebSocketHandlerDecoratorFactory() {\n @Override\n public WebSocketHandler decorate(final WebSocketHandler handler) {\n return new WebSocketHandlerDecorator(handler) {\n\n @Override\n public void afterConnectionEstablished(final WebSocketSession session) throws Exception {\n\n // We will store current user's session into WebsocketSessionHolder after connection is established\n String username = session.getPrincipal().getName();\n WebsocketSessionHolder.addSession(username, session);\n\n super.afterConnectionEstablished(session);\n }\n };\n }\n });\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n存储 websocket 用户会话的类WebsocketSessionHolder。我使用“同步”块来保证线程安全。实际上,这个块并不是昂贵的操作,因为每个方法(addSession 和 closeSessions)都不经常使用(在建立和终止连接时)。这里不需要使用 ConcurrentHashMap 或 SynchronizedMap,因为我们在这些方法中对列表执行了一堆操作。
\n// WebsocketSessionHolder.java\n\npublic class WebsocketSessionHolder {\n\n static {\n sessions = new HashMap<>();\n }\n \n // key - username, value - List of user's sessions\n private static Map<String, List<WebSocketSession>> sessions;\n\n public static void addSession(String username, WebSocketSession session)\n {\n synchronized (sessions) {\n var userSessions = sessions.get(username);\n if (userSessions == null)\n userSessions = new ArrayList<WebSocketSession>();\n\n userSessions.add(session);\n sessions.put(username, userSessions);\n }\n }\n\n public static void closeSessions(String username) throws IOException \n {\n synchronized (sessions) {\n var userSessions = sessions.get(username);\n if (userSessions != null)\n {\n for(var session : userSessions) {\n // I use POLICY_VIOLATION to indicate reason of disconnecting for a client\n session.close(CloseStatus.POLICY_VIOLATION);\n }\n sessions.remove(username);\n }\n }\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n最后一步 - 终止(断开连接)指定的用户 websocket 会话(示例中的“ADMIN”),例如在某些控制器中
\n//PageController.java\n\n@Controller\npublic class PageController {\n @GetMapping("/kill-sessions")\n public void killSessions() throws Exception {\n\n WebsocketSessionHolder.closeSessions("ADMIN");\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n
据我所知,API 不提供您正在寻找的内容,在服务器端您只能检测断开连接事件。如果您想断开某个客户端的连接,我认为您必须采取一些解决方法,例如:
解决方法有点麻烦,但它会起作用。
| 归档时间: |
|
| 查看次数: |
14066 次 |
| 最近记录: |