spring - spring websocket/stomp + rabbitmq - convertAndSend,队列的目标路径
问题描述
我正在学习为我未来的应用程序聊天。那是用户的私人聊天。我正在使用 Stomp,对于经纪人,我想使用 rabbitmq。当我使用 springs SimpleBroker 时一切都很好,但是当我尝试 rabbitmq 时它不起作用。只是rabbitmq代理不接受像spring代理这样的目标路径,带有很多斜杠/topic/user/number。所以我试着用点来解决问题,但我仍然无法让它工作。所以我有这样的事情:
messagingTemplate.convertAndSend("/topic/push." + chatMessage.getRecipientId().toString(),
new ChatNotification(
savedMessage.getId(),
savedMessage.getSenderId(),
savedMessage.getSenderName(),
savedMessage.getContent()
));
所以我认为这样的路径应该可行,但它没有。当我尝试不带点的“/topic/push”时,它也会失败。
配置如下所示:
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/ws")
.setAllowedOrigins("http://localhost:4200").withSockJS();
}
@Override
public boolean configureMessageConverters(List<MessageConverter> messageConverters) {
DefaultContentTypeResolver resolver = new DefaultContentTypeResolver();
resolver.setDefaultMimeType(MimeTypeUtils.APPLICATION_JSON);
MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter();
converter.setObjectMapper(new ObjectMapper());
converter.setContentTypeResolver(resolver);
messageConverters.add(converter);
return false;
}
@Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
// registry.enableSimpleBroker("/topic");
registry.setApplicationDestinationPrefixes("/app");
registry.setUserDestinationPrefix("/topic");
registry.enableStompBrokerRelay("/topic")
.setRelayHost("localhost")
.setRelayPort(61613)
.setClientLogin("lukasz")
.setClientPasscode("user")
.setSystemLogin("lukasz")
.setSystemPasscode("user");
}
}
控制器方法:
@MessageMapping("/chat")
public void processMessage(@Payload ChatMessage chatMessage) {
String chatId = chatRoomMessageService
.getChatId(chatMessage.getSenderId(), chatMessage.getRecipientId(), true)
.orElseThrow(() -> new RuntimeException("Nie ma takiego czatu. Tworzenie nowych kanałów wyłączone"));
chatMessage.setChatId(chatId);
ChatMessage savedMessage = chatMessageService.save(chatMessage);
messagingTemplate.convertAndSend("/topic/push" + chatMessage.getRecipientId().toString(),
new ChatNotification(
savedMessage.getId(),
savedMessage.getSenderId(),
savedMessage.getSenderName(),
savedMessage.getContent()
));
}
还有一个例外:
org.springframework.messaging.MessageDeliveryException: Failed to handle GenericMessage [payload=byte[76], headers={simpMessageType=MESSAGE, contentType=application/json, simpDestination=/topic/push2}] to org.springframework.messaging.support.ExecutorSubscribableChannel$SendTask@2486d6d8 in UserDestinationMessageHandler[DefaultUserDestinationResolver[prefix=/topic/]]; nested exception is java.lang.IllegalArgumentException: Expected destination pattern "/user/{userId}/**"
at org.springframework.messaging.support.ExecutorSubscribableChannel$SendTask.run(ExecutorSubscribableChannel.java:153) ~[spring-messaging-5.3.5.jar:5.3.5]
at org.springframework.messaging.support.ExecutorSubscribableChannel.sendInternal(ExecutorSubscribableChannel.java:100) ~[spring-messaging-5.3.5.jar:5.3.5]
at org.springframework.messaging.support.AbstractMessageChannel.send(AbstractMessageChannel.java:139) ~[spring-messaging-5.3.5.jar:5.3.5]
at org.springframework.messaging.support.AbstractMessageChannel.send(AbstractMessageChannel.java:125) ~[spring-messaging-5.3.5.jar:5.3.5]
at org.springframework.messaging.simp.SimpMessagingTemplate.sendInternal(SimpMessagingTemplate.java:187) ~[spring-messaging-5.3.5.jar:5.3.5]
at org.springframework.messaging.simp.SimpMessagingTemplate.doSend(SimpMessagingTemplate.java:162) ~[spring-messaging-5.3.5.jar:5.3.5]
at org.springframework.messaging.simp.SimpMessagingTemplate.doSend(SimpMessagingTemplate.java:48) ~[spring-messaging-5.3.5.jar:5.3.5]
at org.springframework.messaging.core.AbstractMessageSendingTemplate.send(AbstractMessageSendingTemplate.java:109) ~[spring-messaging-5.3.5.jar:5.3.5]
at org.springframework.messaging.core.AbstractMessageSendingTemplate.convertAndSend(AbstractMessageSendingTemplate.java:151) ~[spring-messaging-5.3.5.jar:5.3.5]
at org.springframework.messaging.core.AbstractMessageSendingTemplate.convertAndSend(AbstractMessageSendingTemplate.java:129) ~[spring-messaging-5.3.5.jar:5.3.5]
at org.springframework.messaging.core.AbstractMessageSendingTemplate.convertAndSend(AbstractMessageSendingTemplate.java:122) ~[spring-messaging-5.3.5.jar:5.3.5]
at luke.socket2.controller.ChatController.processMessage(ChatController.java:42) ~[classes/:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na]
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:564) ~[na:na]
它来自messagingTemplate.convertAndSend()。当我使用 /user 尝试预期的目的地时,它不起作用。Rabbitmq 不接受它。其他路径给了我“不是有效的主题目的地”例外。
所以请帮助我如何发送我的通知。:)
- 使用 rabbitmq 我可以使用 convertAndSendToUser() 方法吗?它看起来如何,与 convertAndSend() 有什么区别?