Spring WebSocket:如何发送给除消息发送者之外的所有订阅者

时间:2020-05-15 21:49:10

标签: spring websocket stomp sockjs

我在这里遵循有关sockJs和Stomp的Spring websocket快速入门指南: https://spring.io/guides/gs/messaging-stomp-websocket/

在这一点上,我的代码看起来像是指南中的代码,并且可以按预期工作。我有一个控制器类,该类具有一种方法,该方法接受传入的消息并将其发送回所有订阅该主题的人。

我想要做的是更改代码,所以我的@MessageMapping带注释的方法将响应发送给所有订阅者,不包括首先发送消息给控制器的订阅者 (因为发件人也订阅了相同的主题,但是我不希望发件人继续接收它自己发送的消息,所以我想这是一个循环)。

我见过许多描述如何向单个订户发送消息的文档,但是还没有见过关于如何向除初始消息发送方以外的所有消息发送消息的人。

在Spring websocket中,有没有内置的方法可以轻松地做到这一点?

1 个答案:

答案 0 :(得分:2)

好,所以我设法找到了一些适合我的解决方案:

我能够按主体用户名过滤订户。

我从org.springframework.messaging.simp.user.SimpUserRegistry获得了所有简化用户, 以及org.springframework.messaging.simp.stomp.StompHeaderAccessor的当前发件人。

我的代码如下:

  @MessageMapping("/game/doStuff")
  public void gameGrid(DoStuffMessage doStuffMessage,
      StompHeaderAccessor headers) {
    sendTo("/game/doStuff", doStuffMessage, headers);
  }

  private void sendTo(String destination, Object payload, StompHeaderAccessor headers) {
    Optional<String> user = Optional.ofNullable(headers.getUser())
        .map(Principal::getName);

    if (user.isPresent()) {
      List<String> subscribers = simpUserRegistry.getUsers().stream()
          .map(SimpUser::getName)
          .filter(name -> !user.get().equals(name))
          .collect(Collectors.toList());

      subscribers
          .forEach(sub -> simpMessagingTemplate.convertAndSendToUser(sub, destination, payload));
    }
  }

客户正在订阅/user/game/doStuff

目前可以使用。我担心的是此代码是否可以水平扩展-如果有人对此有任何见解,我将不胜感激。