首页 > 解决方案 > 从 Spring Boot 服务发送消息不会发送到通过 WebSocket/WebStomp 连接的订阅 Angular 客户端

问题描述

我有一个项目,它使用使用 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,类似于前面的用例,那么它不起作用。

知道我做错了什么或误解了吗?

标签: angularspring-bootmessagingstomp

解决方案


所以我最终做的是将发布时使用的目标字符串更改为“/topic/taskcount”,并将前端更改为订阅“/topic/taskcount”。然后它开始工作。

但是,虽然这可行,但我不确定我是否理解为什么前面没有前缀(在我的情况下为“/comixed”)?我认为这是必要的,因为它是代理的配置方式:

public class ComiXedWebSocketConfig implements WebSocketMessageBrokerConfigurer {
  @Override
  public void configureMessageBroker(final MessageBrokerRegistry registry) {
    registry.enableSimpleBroker("/topic");
    registry.setApplicationDestinationPrefixes("/comixed");
  }

任何人都可以解释一下,或者对使用的名称提供更好的建议吗?


推荐阅读