当前位置: 首页 > 知识库问答 >
问题:

使用spring-websocket和rabbitmq-stomp时,消息不会发送到所有活动的订阅服务器

西门飞翮
2023-03-14

对于将每个消息的副本传递给所有活动订阅者的简单主题目的地,可以使用表单/topic/的目的地。主题目的地支持AMQP主题交换的所有路由模式。

发送到没有活动订阅服务器的主题目的地的消息将被丢弃。

但行为与我的应用程序中的上述声明不一致!

    @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在我的spring 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;
    }
}
}

我对RabbitMQ和Stomp插件的配置有什么错误吗?它在使用SimpleMessageBroker而不是RabbitMQ时工作得很好。

共有1个答案

盛承
2023-03-14

在rabbimq-users组的讨论中解决了这个问题。

我用的是持久订阅,用的是相同的ID,消费者变成了有竞争力的消费者。

在使用持久队列或使用自动删除队列时指定不同的客户端id可以解决这个问题。

 类似资料:
  • 我用的是带Spring靴的网靴。是否有可能向特定订阅发送消息?根据STOMP文档,我使用包含id字段的STOMP头订阅STOMPendpoint,我希望使用此id确定应该接收消息的客户端,但是spring似乎没有使用这个id。我不能只使用sendToUser,因为两个客户端可以具有相同的用户id,例如,如果一个用户有两个打开的浏览器窗口。只有一个特定窗口应接收该消息。 在下面的示例中,我有两个连接

  • 我正在使用Spring stomp websocket框架向客户机发送订阅消息。我们使用ActiveMQ作为消息代理,并使用stomp javascript客户机。Spring 4.1.5和在此体系结构中,消息是通过以下方式发送的: 我只看到一个客户机接收到消息,而另一个没有。通过阅读Spring文档,我了解到这是默认的行为。谁能告诉我我做错了什么。 多谢了。

  • 我正在尝试编写一个Spring服务,它订阅一个外部只读STOMP代理,并读取/处理它发布的消息。 铁路公司将消息推送到主题“/topic/TRAIN\u MVT\u ALL\u TOC”。我可以成功地连接到主题,但似乎无法将侦听器实例化为其消息。 我已经设置了一个Spring@Configuration类来连接它,在运行应用程序之后,它似乎连接正确。 我还创建了消息处理例程,使用@Message映

  • 我正在开发一个利用websockets功能的Spring应用程序。为了使它更健壮,我使用了STOMP/SimpleBrokerMessageHandler,如文档中所述。一切进展顺利,我已经能够非常快速地连接javasctipt客户端,所以我转而使用“AndroidSync”库在Android客户端上工作。 我发现的事实是,Android客户端(我想其他客户端也是如此)在服务器处理订阅请求后没有收

  • 如标题所述,我想使用RabbitMQ向Websocket发送消息。使用AngularJS前端,我想从Websocket读取RabbitMQ消息,并将它们打印到控制台。原则上,我的代码似乎是可行的,尽管我不知道如何获得消息的实际(字符串)内容? 后端:为了创建Websocket并执行路由,我使用Spring Boot和Apache Camel:http://camel.Apache.org/Spri

  • 我正在编写自己的websocket服务器和客户端。我成功地处理了握手并建立了联系。 现在我正在编写send_message函数,它创建了一个合适的框架。下面的例子只是为了这个问题,它不是我最终打算写的,这只是我尝试给我相同的结果的许多方法中的一种。 输入:以上函数应发送 第一个字节 第一位设置为1-,表示这是消息的最后一帧 第二、第三和第四个-所有的零,对于这个例子来说是不相关的 以下四位-000