2

我有一个使用 Spring Boot 和 Stomp over Websocket 的示例。当我将代理注册从 SimpleBrokerRegistration 更改为 StompBrokerRelayRegistration 时,它没有按预期工作。

这是我的 Websocket 配置:

@Configuration
@EnableWebSocketMessageBroker
@ConfigurationProperties(prefix = "spring.artemis")
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {
//...
 @Override
    public void configureMessageBroker(MessageBrokerRegistry config) {
        // If STOMP broker not configured, create an simple fallback
        if (!StringUtil.isEmpty(host) || port > 0) {
            config.enableStompBrokerRelay("/topic", "/queue")
                    .setRelayHost(host)
                    .setRelayPort(port);
        } else {
            config.enableSimpleBroker("/topic", "/queue");
        }
        config.setApplicationDestinationPrefixes("/app");
    }
@Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/hello")
                .withSockJS();
    }
//...
}

和 ArtemisConfig:

  @Configuration
    @ConfigurationProperties(prefix = "spring.artemis")
    public class JmsConfig implements ArtemisConfigurationCustomizer {
        private static final String DEFAULT_TRANSPORT_PROTOCOLS = "STOMP";

        private String host;
        private int port;
        private String protocols;
    // ...
        @Override
        public void customize(org.apache.activemq.artemis.core.config.Configuration configuration) {
            host = StringUtil.hasText(host)?host:TransportConstants.DEFAULT_HOST;
            port = port > 0? port:TransportConstants.DEFAULT_PORT;
            protocols = StringUtil.hasText(protocols)?protocols:DEFAULT_TRANSPORT_PROTOCOLS;
            Set<TransportConfiguration> acceptors = configuration.getAcceptorConfigurations();
            Map<String, Object> params = new HashMap<>();
            params.put(TransportConstants.HOST_PROP_NAME, host);
            params.put(TransportConstants.PORT_PROP_NAME, port);
            params.put(TransportConstants.PROTOCOLS_PROP_NAME, protocols);
            TransportConfiguration tc = new TransportConfiguration(NettyAcceptorFactory.class.getName(), params);
            acceptors.add(tc);
        }
//...
}

然后,我使用这样的 javascript 进行连接:

var socket = new SockJS('/hello');
            stompClient = Stomp.over(socket);
            stompClient.connect('guest', 'guest', function(frame) {
                setConnected(true);
                console.log('Connected: ' + frame);
                stompClient.subscribe('/topic/greetings', function(greeting){
                    showGreeting(greeting.body);
                });
            });

它说找不到队列/topic/greetings

当我像这样使用 SimpMessagingTemplate 时:

messagingTemplate.convertAndSend("/topic/greetings", "WARN: " + warningString());

它抛出一个错误:

StompBrokerRelayMessageHandler : Received ERROR {message=[AMQ339001: Destination does not exist: /topic/greetings]} session=...

我不知道为什么它不能作为 SimpleBroker 工作。

4

3 回答 3

1

您是否事先在 Artemis broker.xml 中创建了此目的地?与 ActiveMQ 不同,您必须这样做,或者在地址设置块中指定自动创建,如下所示:

<!--default for catch all-->
<address-setting match="#">
    <dead-letter-address>jms.queue.DLQ</dead-letter-address>
    <expiry-address>jms.queue.ExpiryQueue</expiry-address>
    <redelivery-delay>0</redelivery-delay>
    <max-size-bytes>10485760</max-size-bytes>
    <message-counter-history-day-limit>10</message-counter-history-day-limit>
    <address-full-policy>BLOCK</address-full-policy>
    <auto-create-jms-queues>true</auto-create-jms-queues>
</address-setting>

在这种情况下,将创建任何目的地。但是,这里有一个问题。当你定义一个队列时,像这样:

<queue name="selectorQueue">
    <entry name="/queue/selectorQueue"/>
    <selector string="color='red'"/>
    <durable>true</durable>
</queue>

它实际上将遵循 jms 命名约定,并具有实际名称jms.queue.selectorQueue. 您也可以尝试映射到该名称。

于 2016-03-11T08:54:16.467 回答
0

出于某种我不知道的原因,Artemis(使用 Stomp 协议)似乎期望主题名称以 开头jms.topic.,而队列名称以jms.queue.

因此,将您的主题重命名为jms.topic.greetings并确保您还将 StompBrokerRelay 配置更改为:

config.enableStompBrokerRelay("jms.topic", "jms.queue")

在此设置中,队列/主题将在需要时自动创建。

(我使用的是 Artemis 1.3。)

于 2017-03-03T14:17:21.443 回答
0

对于正在寻找如何SimpMessageSendingOperations在 2021 年将 Spring (STOMP) 与嵌入式 ActiveMQ Artemis 一起使用的任何人?花了半天时间,我可以告诉你。

添加以下依赖(由于目前存在依赖冲突,请自行查找最新版本)。reactor-netty由于某种原因,spring 目前需要它,您可以尝试在没有它的情况下运行。

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-artemis</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.activemq</groupId>
            <artifactId>artemis-jms-server</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.activemq</groupId>
            <artifactId>artemis-stomp-protocol</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-reactor-netty</artifactId>
        </dependency>

创建以下配置类。这是将嵌入式 artemis 服务器暴露给外部虚拟机连接所必需的。据我了解,默认情况下只使用虚拟机内连接,我还没有找到一种方法来使用这些与 stomp 中继。

@Configuration
public class ArenaArtemisConfiguration {

    private final ArtemisProperties artemisProperties;

    public ArenaArtemisConfiguration(ArtemisProperties artemisProperties) {
        this.artemisProperties = artemisProperties;
    }

    @Bean
    public ArtemisConfigurationCustomizer customizer() {
        return configuration -> {
            try {
                configuration.addAcceptorConfiguration(
                        "netty", "tcp://" + artemisProperties.getHost() + ":" + artemisProperties.getPort()
                );
            } catch (Exception e) {
                throw new IllegalStateException(e);
            }
        };
    }
}

将以下内容添加到您的 application.yml

spring.artemis:
  mode: embedded
  host: localhost
  port: 61616

通过中继配置 webSocket 消息代理(在我们的例子中是 artemis)

@Configuration
public class WebSocketConfiguration extends DelegatingWebSocketMessageBrokerConfiguration {

    private final ArtemisProperties artemisProperties;

    public WebSocketConfiguration(ArtemisProperties artemisProperties) {
        this.artemisProperties = artemisProperties;
    }

    @Override
    public void configureMessageBroker(MessageBrokerRegistry config) {
        config.enableStompBrokerRelay("/your-topics")
                .setRelayHost(artemisProperties.getHost())
                .setRelayPort(artemisProperties.getPort());
    }
}

其余的应该与 with 相同enableSimpleBroker

于 2021-07-18T21:44:11.033 回答