Kri*_*off 5 java spring websocket spring-4 spring-websocket
我使用 Spring 4.3.5 和 WebSocket 以及 SockJS、STOMP 和 SimpleBrokerMessageHandler。
在我的应用程序中,我有三个单独的 WebSocket 端点在不同的地址上运行:/endPointA、/ednpointB、/endpointC 更具体地说,我有三个单独的配置类,并用 @Configuration @EnableWebSocketMessageBroker 注释进行注释。
我还有一个具有 @Autowired SimpMessagingTemplate 的类。
最后,我有三个客户端,每个客户端都连接到一个不同的端点。然而,所有这些都订阅了“相同”的频道地址,即/topic/messages
当我使用SimpMessagingTemplate向/topic/messages发送内容时,所有客户端都会收到此消息。
之后我有两个问题:
我做了一些调查(堆转储分析),发现对于我的配置,我有:
所以我想知道,在所有端点上的消息传播是否是 SimpleBrokerMessageHandler 或 SimpMessagingTemplate 的“功能”。
我在多租户应用程序中遇到了同样的问题,我通过这个线程解决了这个问题:
我的 websocket 端点是:ws://127.0.0.1/my-context-app/ws
,java 配置文件是:
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/ws").setAllowedOrigins("*");
registry.addEndpoint("/ws").setAllowedOrigins("*").withSockJS();
}
}
Run Code Online (Sandbox Code Playgroud)
我的 websocket 队列 url 表单以tenant-id: 为前缀/[tenant-id]/[url-of-queue]。
每个客户端都订阅自己的租户 ID。WebSocketSecurityConfig.configureInbound(MessageSecurityMetadataSourceRegistry)由于方法和具有“websocket-queue-subscription-security-check”方法的自定义 spring bean,它无法订阅另一个客户端的队列:
@Configuration
public class WebSocketSecurityConfig extends AbstractSecurityWebSocketMessageBrokerConfigurer {
protected void configureInbound(MessageSecurityMetadataSourceRegistry messages) {
messages
.simpSubscribeDestMatchers("/**")
.access("@customWSSecurityCheck.isSubscriptionAllowed(authentication, message)");
}
}
Run Code Online (Sandbox Code Playgroud)
我的自定义 bean 名为 customWSSecurityCheck 检查是否允许经过身份验证的用户订阅队列。请记住,使用附加的tenantId属性CustomAuthentication来实现org.springframework.security.core.Authentication,该属性由自定义Spring安全过滤器/身份验证方法中未提及的附加代码填充:
@Bean()
public class CustomWSSecurityCheck {
public boolean isSubscriptionAllowed(CustomAuthentication authentication, Message message) {
StompHeaderAccessor sha = StompHeaderAccessor.wrap(message);
String url = sha.getDestination().substring(1);
String tenantId = url.substring(0, url.indexOf("/"));
return tenantId.equals(authentication.getTenantId());
}
}
Run Code Online (Sandbox Code Playgroud)
当然,这涉及到服务器发送的每条消息都应该以正确的租户 ID 为前缀:MessagingService.convertAndSend("[tenant-id]/[url-of-queue]", messagePayload)
| 归档时间: |
|
| 查看次数: |
2802 次 |
| 最近记录: |