Прямое сообщение пользователя не работает с Spring Websocket

Я пытаюсь отправлять прямые сообщения пользователю. Приложение не выполнило аутентификацию, поэтому существует временное решение для создания пользователей сеанса веб-сокета, как вы можете видеть в добавленном коде.

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfiguration implements WebSocketMessageBrokerConfigurer {

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {

        registry.addEndpoint("/ws")
                .setHandshakeHandler(new CustomHandshakeHandler())
                .withSockJS();
    }

    @Override
    public void configureMessageBroker(MessageBrokerRegistry registry) {
        registry.enableSimpleBroker("/queue/", "/topic/", "/exchange/");
        registry.setApplicationDestinationPrefixes("/app");
    }

    // only for dev purpose
    public static class CustomHandshakeHandler extends DefaultHandshakeHandler {

        @Override
        protected Principal determineUser(ServerHttpRequest request, WebSocketHandler wsHandler, Map<String, Object> attributes) {
            String username = "user-123";
            return new StompPrincipal(username);
        }

        @Data
        @AllArgsConstructor
        @NoArgsConstructor
        public static class StompPrincipal implements Principal {
            private String name;
        }
    }
}

Вот мой слушатель RabbitMQ, который обрабатывает событие с сообщением и отправляет прямое сообщение тестовому пользователю user-123 через веб-сокеты:

@RabbitListener(queues = "${event.queue.message-created}")
public void handleMessageCreatedEvent(MessageCreatedEvent event) {
    String devUser = "user-123";
    log.info("MSG received {}.", event); 
    simpMessagingTemplate.convertAndSendToUser(devUser, "/exchange/amq.direct/chat.message", event);
}

Сообщение обрабатывается кроличьим слушателем и отправляется с помощью простого шаблона обмена сообщениями, но не доходит до клиентского интерфейса в javascript.

Вот как я пытаюсь обрабатывать эти сообщения:

$(function () {
    var stompClient;
    var wrappedSocket = {

        init: function (url) {
            stompClient = Stomp.over(new SockJS(url));
        },
        connect: function (successCallback, errorCallback) {

            stompClient.connect({}, function (frame) {
                successCallback(frame)
            }, function (error) {
                errorCallback(error)
            });
        },
        subscribe: function (destination, callback) {
            stompClient.subscribe(destination, function (message) {
                callback(message)
            });
        },
        send: function (destination, headers, object) {
            stompClient.send(destination, headers, object);
        }
    };


    wrappedSocket.init('/ws');

    wrappedSocket.connect(
        function (frame) {
            console.info('connected', frame)
        }, function (err) {
            console.error('not connected', err)
        }
    );

    wrappedSocket.subscribe("/user/exchange/amq.direct/chat.message", function(message) {
        console.log('NEW PRIVATE MESSAGE', message)
    });

    console.log("ready!");
});

Я вижу в консоли браузера, что клиент успешно подключен и начинает подписываться на данный канал, но сообщение не получено.

Можете ли вы сказать, как это исправить? Спасибо.


person Denis Stephanov    schedule 27.07.2020    source источник


Ответы (1)


Подписка должна быть инициализирована после установления соединения, поэтому попробуйте вызвать wrappedSocket.subscribe() при успешном обратном вызове.

person Martin Ondo-Eštok    schedule 27.07.2020