集成 Spring 控制器消息映射和 Artemis
Integrating Spring controllers message mapping and Artemis
我正在研究切换到 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 controller 不喜欢 - jms.queue.greetings.
中没有消息出现
我可以通过使代码不那么漂亮,使用一些手工注入的服务订阅所需的队列来强制解决这个问题,但那样我会失去 Spring sockJS 魔法 - Artemis(不像 RabbitMQ)似乎没有为 Stomp 提供 http
端点,连接到 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 }));
...
根据您的更新
当发送到 jms.queue.greeting 时,您告诉 spring 如果您想向控制器发送消息,则无需输入任何控制器即可将您的请求直接重定向到 Broker然后将其转发给代理,您应该根据您的配置将其发送到 app.greeting 并且该控制器会将其转发回 jms.queue.greeting
如果您正在使用 .作为定界符在所有注释中使用它
检查这个 diagram 它会告诉你发送到 /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 被硬编码为 / 用于用户解析。
我正在研究切换到 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 controller 不喜欢 - jms.queue.greetings.
中没有消息出现我可以通过使代码不那么漂亮,使用一些手工注入的服务订阅所需的队列来强制解决这个问题,但那样我会失去 Spring sockJS 魔法 - Artemis(不像 RabbitMQ)似乎没有为 Stomp 提供 http
端点,连接到 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 }));
...
根据您的更新
当发送到 jms.queue.greeting 时,您告诉 spring 如果您想向控制器发送消息,则无需输入任何控制器即可将您的请求直接重定向到 Broker然后将其转发给代理,您应该根据您的配置将其发送到 app.greeting 并且该控制器会将其转发回 jms.queue.greeting
如果您正在使用 .作为定界符在所有注释中使用它
检查这个 diagram 它会告诉你发送到 /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 被硬编码为 / 用于用户解析。