2

我正在研究切换到 WildFly 10,然后是 Artemis。我已经建立了一个简单的 Spring Websocket 项目,如下所述:https ://spring.io/guides/gs/messaging-stomp-websocket/ 。该项目的核心是 WebSocketConfig:

@Override
public void configureMessageBroker(MessageBrokerRegistry config) {
    config.enableStompBrokerRelay("/queue/", "/topic/");
    config.setApplicationDestinationPrefixes("/app");
}

和控制器:

@MessageMapping("/hello")
@SendTo("/topic/greetings")
public Greeting greeting(HelloMessage message) throws Exception {
    return new Greeting("Hello, " + message.getName() + "!");
}

这就像 ActiveMQ 的魅力一样,在代理端不需要额外的配置。

知道 Artemis 需要预先创建的目的地,或者特别提到自动队列创建,我将其添加到我的 broker.xml 中:

<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>
</address-settings>

但是,这并没有像我预期的那样工作,经纪人仍然拒绝创建/queue/greetings. 因此,我进行了更多研究,发现实际上 Artemis 喜欢队列是带有jms.queue.*前缀的名称。我将队列重命名为jms.queue.greetings并对 Spring 代码进行了以下更改: 配置:

...
config.setPathMatcher(new AntPathMatcher("."));
...

控制器:

...
@SendTo("jms.queue.greetings")
...

据我了解,这应该迫使我的控制器向该队列发送消息。Broker 喜欢这种变化并最终创建了队列,但另一方面 Spring 控制器却没有——jms.queue.greetings 中没有出现任何消​​息。

我可以通过使代码不那么漂亮来强制解决这个问题,使用一些手工注入的服务订阅所需的队列,但是这样我就会失去 Spring sockJS 的魔力——Artemis(不像 RabbitMQ)似乎没有http为 Stomp 提供端点, 连接到ws://只会导致 CORS 错误。似乎也没有内置的 CORS 支持。

对于如何克服这个问题,我将不胜感激。

编辑:我的 JS 看起来像这样:

var ws = new SockJS('/hello');
client = Stomp.over(ws);
...
client.connect(login, passcode, function(frame) {
    client.debug("connected to Stomp");
    ....
    client.subscribe('jms.queue.greetings', function(message) {
        ...
    });
});
...
client.send("jms.queue.greetings", {}, JSON.stringify({ 'name': text }));
...
4

1 回答 1

1

根据您的更新

发送到jms.queue.greeting时,您是在告诉 spring 将您的请求直接重定向到 Broker 而不输入任何控制器,如果您想将消息发送到控制器,然后将其转发给代理,您应该根据您的配置将其发送到app.greeting并且控制器会将其转发回jms.queue.greeting

如果您正在使用 . 作为分隔符在所有注释中使用它

检查此,它将向您显示发送到 /app 和 /queue 或 /topic 之间的区别第一个进入控制器第二个只是重定向

我正在使用以下内容,并且能够发送和接收消息

//Configuration
    @Override
        public void configureMessageBroker(MessageBrokerRegistry config) {
            config.enableStompBrokerRelay("jms.topic", "jms.queue")
            .setRelayHost("192.168.65.24")
            .setRelayPort(5445)
            .setSystemLogin("root")
            .setSystemPasscode("XXXXX")
            .setClientLogin("root")
            .setClientPasscode("XXXXX");
            config.setApplicationDestinationPrefixes("app");
            //config.setUserDestinationPrefix("user"); 
            config.setPathMatcher(new AntPathMatcher("."));
        }

        @Override
        public void registerStompEndpoints(StompEndpointRegistry registry) {
            registry.addEndpoint("/stomp");
        }


//Subscribtion
     stompClient.subscribe('jms.queue.call', function(greeting){
                        showGreeting(JSON.parse(greeting.body).name);
                    });

//Sending
    stompClient.send("jms.queue.call", {}, JSON.stringify({ 'name': message }));

artemis 仍然存在的一个问题是 /user/ ,其中 DefaultUserDestinationResolver 使用 / 硬编码用于用户解析。

于 2016-03-11T18:52:05.867 回答