Java 使用弹簧腹板套筒';具有多端点配置的s SimpMessageTemplate
我将Spring4.3.5和WebSocket与SockJS、STOMP和SimpleBrokerMessageHandler一起使用 在我的应用程序中,有三个独立的WebSocket端点运行在不同的地址上:/endPointA、/ednpointB、/endpointC 更具体地说,我用@configuration@EnableWebSocketMessageBroker注释了三个独立的配置类 我还有一个类有@Autowired SimpMessagingTemplate 最后,我有三个客户端,每个客户端连接到一个不同的端点。 然而,它们都订阅了“相同”的频道地址,即/topic/messagesJava 使用弹簧腹板套筒';具有多端点配置的s SimpMessageTemplate,java,spring,websocket,spring-websocket,spring-4,Java,Spring,Websocket,Spring Websocket,Spring 4,我将Spring4.3.5和WebSocket与SockJS、STOMP和SimpleBrokerMessageHandler一起使用 在我的应用程序中,有三个独立的WebSocket端点运行在不同的地址上:/endPointA、/ednpointB、/endpointC 更具体地说,我用@configuration@EnableWebSocketMessageBroker注释了三个独立的配置类 我还有一个类有@Autowired SimpMessagingTemplate 最后,我有三个客户端
- ClientOne已连接到端点A
- ClientTwo已连接endpointB
- 客户端三已连接到端点C
- SimpMessageTemplate的三个实例,但我始终使用同一个实例发送消息(因为@Autowire-另外,我正在打印SimpMessageTemplate.toString()
- SimpleBrokerMessageHandler的一个实例
- SockJsWebSocketHandler的三个实例
因此,我想知道,在所有端点上的消息传播是否是SimpleBrokerMessageHandler或SimpMessageTemplate的“功能”。我在多租户应用程序中遇到了同样的问题,这要归功于: 我的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队列订阅安全检查”方法的自定义spring bean,它无法订阅另一个客户端的队列:
@Configuration
public class WebSocketSecurityConfig extends AbstractSecurityWebSocketMessageBrokerConfigurer {
protected void configureInbound(MessageSecurityMetadataSourceRegistry messages) {
messages
.simpSubscribeDestMatchers("/**")
.access("@customWSSecurityCheck.isSubscriptionAllowed(authentication, message)");
}
}
我的名为customWSSecurityCheck的自定义bean检查是否允许经过身份验证的用户在队列上订阅。请记住,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(“[租户id]/[url Of queue]”,messagePayload)
我也有类似的问题。你还记得你是怎么解决的吗?嗨,不幸的是我们没有。我们接受现实——这是概念验证应用程序。虽然我仍然好奇它背后的原因是什么。原因取决于你的配置。可能所有的客户端都订阅了相同的主题。相反,它们应该订阅各自的队列。虽然我认为在具有不同名称的端点之间存在主题隔离,但它们订阅了相同的主题。不,消息传递不是这样工作的。隔离可以通过专用队列完成。