stomp-websocket从服务器端拒绝用户订阅或取消订阅

z3yyvxxp  于 2021-07-24  发布在  Java
关注(0)|答案(1)|浏览(878)

我试图强制取消订阅一个用户时,他被管理员禁止,并阻止他订阅时,他被禁止。禁止状态保存在我的数据库中。我现在有一个拦截器来拦截 preSend 但是当我抛出一个异常时,连接就关闭了。在不关闭套接字连接的情况下,是否仍可以拒绝订阅消息?

@Override
  public Message<?> preSend(@NonNull Message<?> message, @NonNull MessageChannel channel) {
    StompHeaderAccessor headerAccessor = StompHeaderAccessor.wrap(message);
    if (StompCommand.SUBSCRIBE.equals(headerAccessor.getCommand())) {
      checkIsBanned(headerAccessor.getDestination(), headerAccessor.getUser());
    }
    return message;
  }

  private void checkIsBanned(String destination, Principal principal) {
    if (destination == null || !destination.matches(CHAT_TOPIC_REGEX)) {
      return;
    }
    String errorMessage = resourceBundle.getMessage("err.channel.banned");
    if (!(principal instanceof OAuth2Authentication) || !(((OAuth2Authentication) principal).getPrincipal() instanceof SUserDetails)) {
      throw new MessagingException(errorMessage);
    }
    String channelId = destination.split("/")[3];
    Long profileId = getProfileId(principal);
    if (profileId == null) {
      throw new MessagingException(errorMessage);
    }
    channelUserRepo.findByChannelIdAndUserId(channelId, profileId).filter(ChannelUser::isBanned).orElseThrow(() -> new MessagingException(errorMessage));
  }

  private Long getProfileId(Principal principal) {
    return ((SUserDetails) ((OAuth2Authentication) principal).getPrincipal()).getProfileId();
  }

我还尝试在管理员禁止用户时通过从 userRegistry 并删除他的订阅,但这没有起作用。有什么办法也能做到吗?

ztmd8pv5

ztmd8pv51#

我想我通过返回null成功地拒绝了订阅 preSend 它将忽略订阅消息,而不是抛出错误。您还可以通过套接字向用户发送通知来通知用户。

public ChatInterceptor(ResourceBundle resourceBundle, ChannelUserRepository channelUserRepo, @Lazy SimpMessagingTemplate socket) {
    this.resourceBundle = resourceBundle;
    this.channelUserRepo = channelUserRepo;
    this.socket = socket;
  }

  @Override
  public Message<?> preSend(@NonNull Message<?> message, @NonNull MessageChannel channel) {
    StompHeaderAccessor headerAccessor = StompHeaderAccessor.wrap(message);
    if (StompCommand.SUBSCRIBE.equals(headerAccessor.getCommand())) {
      if (checkIsBanned(headerAccessor.getDestination(), headerAccessor.getUser())) {
        socket.convertAndSendToUser(getSocketUsername(headerAccessor.getUser()), ServicePath.NOTIFICATION,
            new SocketResponse(resourceBundle.getMessage("err.channel.banned"), ERROR));
        return null;
      }
    }
    return message;
  }

相关问题