我有一个基于spring websocket over stomp(由spring boot 1.5.1提供支持)的web应用程序。我使用Rabbitmq(3.6.6)和stomp插件作为全功能代理。当使用spring-websocket和rabbitmq-stomp时不会发送消息给所有活动用户
据the doc of stomp,从/主题目标的消息/将被传递到所有活跃用户。
主题目的地
对于简单的主题目的地其中递送每个消息的副本 到所有活动用户,形式 /主题的目的地/都可以使用。主题目标支持AMQP主题交换的所有路由 模式。
邮件发送到一个没有活跃用户 被直接丢弃的主题目的地。
但行为是不是符合上述声明在我的应用程序!
我在两个浏览器中打开了相同的页面。因此有两个客户端连接到websocket服务器。他们都订购了从/topic/
开始的相同目的地。
我发送消息到目的地/topic/<route key>
,但只有一个客户端后,将收到消息。两个客户端将旋转以接收来自相同目的地的消息。
在我的春天的服务器端应用程序,我将消息发送到目的地像下面,
@Secured(User.ROLE_USER)
@MessageMapping("/comment/{liveid}")
@SendTo("/topic/comment-{liveid}")
public CommentMessage userComment(@DestinationVariable("liveid") String liveid,
@AuthenticationPrincipal UserDetails activeUser, UserComment userComment) {
logger.debug("Receiving comment message '{}' of live '{}' from user '{}'.",
userComment,liveid, activeUser.getUsername());
final User user = userService.findByUsername(activeUser.getUsername()).get();
return CommentMessage.builder().content(userComment.getContent()).sender(user.getNickname())
.senderAvatar(user.getAvatar()).build();
}
在我的客户端,它赞同像下面的持久主题,
$stomp.subscribe('/topic/comment-' + $scope.lives[i].id, function(payload, headers, res) {
// do something
}, {
'durable': true,
'auto-delete': false
});
下面是在我的弹簧应用程序的websocket的配置,
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractSessionWebSocketMessageBrokerConfigurer<ExpiringSession> {
@Value("${stompBroker.host:localhost}")
String brokerHost;
@Value("${stompBroker.port:61613}")
int brokerPort;
@Value("${stompBroker.login:guest}")
String brokerLogin;
@Value("${stompBroker.passcode:guest}")
String brokerPasscode;
@Value("${stompBroker.vhost:myvhost}")
String brokerVHost;
@Override
protected void configureStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/live/ws").withSockJS();
}
@Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
registry.enableStompBrokerRelay("/topic/").setRelayHost(brokerHost).setRelayPort(
brokerPort).setSystemLogin(brokerLogin).setSystemPasscode(brokerPasscode).setVirtualHost(brokerVHost);
/**
* Both of two subscribers can receive the message if using simple broker
registry.enableSimpleBroker("/topic/");
*/
registry.setApplicationDestinationPrefixes("/app");
}
@Configuration
public class WebSocketSecurityConfig extends AbstractSecurityWebSocketMessageBrokerConfigurer {
@Override
protected void configureInbound(MessageSecurityMetadataSourceRegistry messages) {
messages.simpDestMatchers("/app/*").hasRole("USER");
}
@Override
protected boolean sameOriginDisabled() {
return true;
}
}
}
是否有任何错误的我的配置RabbitMQ和Stomp插件的使用?当使用SimpleMessageBroker
而不是RabbitMQ时,它运行良好。