gpt4 book ai didi

java - 使用 Spring WebSocket 的 SimpMessagingTemplate 进行多端点配置

转载 作者:行者123 更新时间:2023-12-02 04:27:37 25 4
gpt4 key购买 nike

我正在使用 Spring 4.3.5 和 WebSocket 以及 SockJS、STOMP 和 SimpleBrokerMessageHandler。

在我的应用程序中,我有三个独立的 WebSocket 端点在不同的地址上运行:/endPointA、/ednpointB、/endpointC更具体地说,我有三个单独的配置类,并用 @Configuration @EnableWebSocketMessageBroker 注释进行注释。

我还有一个具有 @Autowired SimpMessagingTemplate 的类。

最后,我有了三个客户端,每个客户端都连接到一个不同的 EndPoint。然而,所有这些都订阅了“相同” channel 地址,即/topic/messages

  • ClientOne 已连接端点A
  • ClientTwo 已连接端点B
  • ClientThree 已连接端点C

当我使用 SimpMessagingTemplate/topic/messages 发送内容时,所有客户端都会收到此消息。

之后我有两个问题:

  1. 有没有办法“隔离”Web Socket 端点,以便消息不会传播到所有端点?
  2. 为什么会发生这种情况?

我做了一些调查(堆转储分析),我发现对于我的配置,我有:

  • SimpMessagingTemplate 的三个实例,但是我始终使用同一个实例来发送消息(因为 @Autowire - 另外我正在打印 SimpMessagingTemplate.toString())。
  • SimpleBrokerMessageHandler的一个实例
  • SockJsWebSocketHandler的三个实例

所以我想知道,在所有端点上的消息传播是否是 SimpleBrokerMessageHandler 或 SimpMessagingTemplate 的“功能”。

最佳答案

我在 Multi-Tenancy 应用程序中遇到了同样的问题,我通过 this thread 解决了这个问题:

我的 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();
}
}

我的 websocket 队列 URL 表单以租户 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)");
}

}

我的自定义 bean 名为 customWSSecurityCheck 检查是否允许经过身份验证的用户订阅队列。请记住,CustomAuthentication使用附加的tenantId属性实现了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());
}
}

当然,这涉及到服务器发送的每条消息都应该以正确的租户 ID 为前缀: MessagingService.convertAndSend("[tenant-id]/[url-of-queue]", messagePayload)

关于java - 使用 Spring WebSocket 的 SimpMessagingTemplate 进行多端点配置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43208097/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com