Отправить STOMP ERROR из программы Spring Websocket

У меня есть приложение Spring Websocket Stomp, которое принимает запросы SUBSCRIBE.

В приложении у меня есть обработчик для SUBSCRIBE, то есть

 @Component
 public class SubscribeStompEventHandler implements ApplicationListener<SessionSubscribeEvent> {

    @Override
    public void onApplicationEvent(SessionSubscribeEvent event) {}
 }

который я использую для проверки подписки.

Я бы проверил что-нибудь в onApplicationEvent и отправил сообщение STOMP ERROR обратно клиенту из этой функции.

Я нашел этот рецепт Как отправить сообщение об ОШИБКЕ на Клиенты STOMP с Spring WebSocket? но мне нужно понять, как получить outboundChannel.

Я пробовал также следующий код:

   public void sendStompError(SimpMessagingTemplate simpMessagingTemplate, String sessionId, String topic, String errorMessage) {

    StompHeaderAccessor headerAccessor = StompHeaderAccessor.create(StompCommand.ERROR);
    headerAccessor.setMessage(errorMessage);
    headerAccessor.setSessionId(sessionId);
    headerAccessor.setLeaveMutable(true);
    simpMessagingTemplate.convertAndSendToUser(sessionId, topic, new byte[0], headerAccessor.getMessageHeaders());       
}

и я попытался сделать тему какой-то темой подписки и темой /queue/error. Однако я не видел, чтобы сообщения передавались клиенту.

В клиенте я использую:

      stompClient.connect(headers
                , function (frame) {
                    console.log("Conn OK " + url);               
                }, function (error) {                       
                    console.log("Conn NOT OK " + url + ": " + JSON.stringify(error));
                });
        }

и моя цель состоит в том, чтобы вызвать функцию (ошибку), когда я отправляю STOMP ERROR.

Пожалуйста, посоветуйте мне, как именно я могу отправить правильную STOMP ERROR, например. путем получения Outboundchannel.


person Askar Ibragimov    schedule 22.09.2016    source источник


Ответы (1)


Вы можете отправить ERROR сообщение следующим образом:

StompHeaderAccessor headerAccessor = StompHeaderAccessor.create(StompCommand.ERROR);
headerAccessor.setMessage(error.getMessage());
headerAccessor.setSessionId(sessionId);
this.clientOutboundChannel.send(MessageBuilder.createMessage(new byte[0], headerAccessor.getMessageHeaders()));

Следующего достаточно, чтобы ввести этот clientOutboundChannel:

 @Autowired
 @Qualifier("clientOutboundChannel")
 private MessageChannel clientOutboundChannel;

Просто потому, что бин clientOutboundChannel объявлен в файле AbstractMessageBrokerConfiguration.

ОБНОВЛЕНИЕ

STOMP ERROR всегда закрывает соединение? Я получаю этот эффект. Код 1002.

Да, это. См. StompSubProtocolHandler.sendToClient():

       if (StompCommand.ERROR.equals(command)) {
            try {
                session.close(CloseStatus.PROTOCOL_ERROR);
            }
            catch (IOException ex) {
                // Ignore
            }
        }
person Artem Bilan    schedule 22.09.2016
comment
Артем, уточните пожалуйста: STOMP ERROR всегда закрывает соединение? Я получаю этот эффект. Код 1002. - person Askar Ibragimov; 23.09.2016
comment
Смотрите и ОБНОВЛЯЙТЕ в моем ответе. - person Artem Bilan; 23.09.2016
comment
Как StompClient получает сообщение об ошибке? Какая-то специальная конфигурация? - person hurelhuyag; 22.01.2020
comment
Так как StompCommand.ERROR всегда закрывает соединение, то у нас нет выбора и мы отправляем ошибки клиенту как обычные StompCommand.MESSAGE. - person Artem Bilan; 22.01.2020
comment
@ArtemBilan Знаете ли вы какую-либо альтернативу использованию SpringBoot для правильной отправки кадров ОШИБКИ и ожидания некоторого времени, пока клиент не сможет их обработать? - person Fernando Miguélez; 17.11.2020
comment
как заставить сеанс закрыть соединение? - person python; 08.03.2021