Ich habe eine Web-App basierend auf Feder Websocket über Stomp (powered by Spring Boot 1.5.1). Und ich benutze Rabbitmq (3.6.6) mit Stomp-Plugin als Full-Feature-Broker.Nachricht wird nicht an alle aktiven Abonnenten gesendet, wenn spring-websocket und rabbitmq-stomp verwendet werden
Gemäß the doc of stomp wird die Nachricht mit dem Ziel aus/topic/an alle aktiven Abonnenten gesendet.
Thema Ziele
Für einfache Thema Ziele, die jeder Nachricht an alle aktiven Abonnenten, Destinationen der Form /Thema eine Kopie liefern/verwendet werden. Zweigziele unterstützen alle Routingmuster des AMQP-Themenaustauschs.
Nachrichten, die an ein Topic-Ziel gesendet werden, das keine aktiven Teilnehmer hat werden einfach verworfen.
Aber das Verhalten ist NICHT Übereinstimmung mit obigen Deklaration in meiner App!
Ich habe die gleiche Seite in zwei Browsern geöffnet. Daher verbinden sich zwei Clients mit dem Websocket-Server. Beide haben das gleiche Ziel mit /topic/
abonniert.
Nachdem ich die Nachricht an das Ziel gesendet /topic/<route key>
, aber nur ein Client wird die Nachricht erhalten. Die zwei Clients werden rotieren, um die Nachrichten vom selben Ziel zu empfangen.
In meiner Feder Server-Seite app, schicke ich die Nachrichten an Ziel wie unten,
@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();
}
In meinem Client-Seite, es die dauerhafte Thema wie unten abonniert,
$stomp.subscribe('/topic/comment-' + $scope.lives[i].id, function(payload, headers, res) {
// do something
}, {
'durable': true,
'auto-delete': false
});
Unterhalb der ist Konfiguration von Websocket in meiner Feder App,
@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;
}
}
}
Gibt es irgendwelche falsche von meiner Konfig von RabbitMQ und Stomp Plugin? Es funktioniert gut, wenn Sie SimpleMessageBroker
nicht RabbitMQ verwenden.