我有一个项目,它使用使用 Spring 消息传递和 websockets 的后端 Spring Boot 服务器与使用 STOMP(通过 WebStomp)的 Angular 前端进行通信。
为了设置一些基础知识,我们使用 /comixed 作为我们的应用程序前缀,以及 /topic/、/queue/ 和/secured/ 作为简单代理的前缀。
我可以(并且确实)看到订阅从前端到后端。例如:
this.subscription = this.webSocketService.subscribe(
'/comixed/taskcount',
frame => {
const message = JSON.parse(frame.body) as TaskCountMessage;
this.logger.debug('Task message:', message);
this.store.dispatch(
setTaskCount({
count: message.count
})
);
}
);
在以下方法中导致断点:
@SubscribeMapping("/taskcount")
public List<TaskCountMessage> subscribeToTaskCounts() {...}
开火。
但是当我稍后尝试使用以下方法从应用程序的另一部分向订阅的客户端发布消息时:
this.messagingTemplate.convertAndSend(
"/topic/taskcount", new TaskCountMessage(this.workerTaskAdaptor.getTaskCount()));
没有任何东西到达订阅的客户端。我在 WebStomp 中启用了调试,我看到了客户端订阅主题的位置:
[DEBUG]: Subscribing to topic: /comixed/taskcount
10:27:33.292 web-socket.service.ts:47 [DEBUG]: [STOMP] >>> SUBSCRIBE
id:sub-1615476453292-968
destination:/comixed/taskcount
所以我不确定为什么消息没有从后端流到前端。使用“/topic/”有问题吗?我真的找不到任何明确的帮助来说明 STOMP 和 Spring 在这些前缀之间有什么区别,何时使用它们以及何时不使用它们。我熟悉消息传递概念,但这个概念真的让我感到困惑。非常感谢任何帮助。
(编辑)
虽然我确实设法最终使这个用例的事情顺利进行(通过让发布者和订阅者都使用 /topic/taskcount),但我添加了另一个在以下情况下不起作用的用例全部。
我添加了一个返回初始订阅数据的方法:
@SubscribeMapping("/scantypes")
public List<ScanTypeMessage> getScanTypes() {
log.info("Getting all scan types");
return this.scanTypeService.findAll().stream()
.map(scanType -> new ScanTypeMessage(LibraryAction.ADD, scanType))
.collect(Collectors.toList());
}
如果订阅者使用/comixed/scantypes,则该方法仅被调用。如果我使用 /topic/scantypes,类似于前面的用例,那么它不起作用。
知道我做错了什么或误解了吗?
答案 0 :(得分:0)
所以我最终做的是将发布时使用的目标字符串更改为“/topic/taskcount”,并将前端更改为订阅“/topic/taskcount”。然后它开始工作。
但是,虽然这有效,但我不确定我是否理解为什么在它前面没有前缀(在我的例子中是“/comixed”)?我认为这是必要的,因为这是代理的配置方式:
public class ComiXedWebSocketConfig implements WebSocketMessageBrokerConfigurer {
@Override
public void configureMessageBroker(final MessageBrokerRegistry registry) {
registry.enableSimpleBroker("/topic");
registry.setApplicationDestinationPrefixes("/comixed");
}
谁能解释一下,或者对使用的名称提出更好的建议?