Код ошибки 200 при открытии соединения с веб-сокетом с помощью spring-boot-starter-websocket - PullRequest
0 голосов
/ 19 апреля 2019

Я использую spring-boot-starter-websocket и пытаюсь создать websocket без опции sockJS.Я пользуюсь 1.5.4.RELEASE версией.Я использую расширение Chrome «Простой клиент веб-сокета» для тестирования своего веб-сокета.Я получаю сообщение об ошибке

: ошибка при рукопожатии WebSocket: непредвиденный код ответа: 200

при попытке открыть соединение с моей веб-розеткой.Развертывание на сервере Liberty.

Я пытался проверить различные решения (например, this ), но большинство из них указывают на добавление "/ websocket" в конце, чтобы преодолеть эту проблему.,Но когда я добавляю это, я получаю ошибку 404.

Мой код:

@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {
    Logger logger = LogManager.getLogger(WebSocketConfig.class);

    @Bean
    public ServletServerContainerFactoryBean createWebSocketContainer() {
        logger.info("In WebSocketConfig, ServletServerContainerFactoryBean.. ");
        ServletServerContainerFactoryBean container = new ServletServerContainerFactoryBean();
        container.setMaxBinaryMessageBufferSize(1024000);
        return container;
    }

    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {

        logger.info("In WebSocketConfig, registerWebSocketHandlers.. ");
        registry.addHandler( notificationHandler(), "/smnotifname")
                .setAllowedOrigins("*");    // allow all origins;
    }

    /**
     * @return one notification handler bean for all WebSocket connections.
     */
    @Bean
    public WebSocketHandler notificationHandler() {
        logger.info("In WebSocketConfig, notificationHandler.. ");
        return new NotificationHandler();
    }

}

Когда мой сервер запускается, я вижу все 3 оператора журнала, для всех 3 напечатанных методов.

Вот мой класс NotificationHandler.

public class NotificationHandler extends TextWebSocketHandler {

    Logger logger = LogManager.getLogger(NotificationHandler.class);


    @Override
    public void afterConnectionEstablished(WebSocketSession session)
            throws IOException {
        logger.info("In NotificationHandler, afterConnectionEstablished.. ");
        session.sendMessage(new TextMessage("Hello !"));
    }

    @Override
    public void handleTextMessage(WebSocketSession session, TextMessage message) throws IOException {
        logger.info("In NotificationHandler, handleTextMessage.. ");
        session.sendMessage(new TextMessage("Hello Text Message!"));
    }

    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) {
        logger.info("In NotificationHandler, afterConnectionClosed.. ");
    }

}

Когда я использую url - wss: // serverurl / smnotifname в расширении «Простой клиент веб-сокета», я получаю сообщение об ошибке »:Ошибка во время рукопожатия WebSocket: Неожиданный код ответа: 200 '.

Я вижу, как в журналах печатается метод регистрации afterConnectionEstablished.

URL - wss: // <> / smnotifname / websocket дает 404. У меня уже есть .setAllowedOrigins ("*") в коде.

Это приложение Spring MVC, сугловой код в нем.

Может кто-нибудь помочь мне решить мою проблему?Любая помощь очень ценится.

РЕДАКТИРОВАТЬ 1 - 04/22 :

Похоже, что даже обновление http до websockets (который направляет в класс NotificationHandler) вызывается, процесс возвращает 200 кодов.Но я не могу понять, какая часть Spring возвращает этот ответ. Может ли кто-нибудь подсказать мне, как устранить эту проблему дальше?Спасибо и признателен за любую помощь.

РЕДАКТИРОВАТЬ 2 - 04/22 :

Если я добавлю .addInterceptors(new UriTemplateHandshakeInterceptor());на мой метод registerWebSocketHandlers, с кодом, как показано ниже.Я попытался вручную переопределить код возврата на 101. В этом случае соединение открывается, но когда я пытаюсь отправить сообщение в открытом канале, я получаю 404. Поэтому я предполагаю, что принудительное открытие соединения вызывает что-то другое,Поэтому мне действительно нужно понять, что мешает получить ответ 101 и отправить код ответа 200.

private class UriTemplateHandshakeInterceptor
        implements HandshakeInterceptor {

    @Override
    public boolean beforeHandshake(ServerHttpRequest request,
            ServerHttpResponse response, WebSocketHandler wsHandler,
            Map<String, Object> attributes) throws Exception {

        logger.info("In WebSocketConfig, UriTemplateHandshakeInterceptor, HandshakeInterceptor.. ");
        /* Retrieve original HTTP request */
        HttpServletRequest origRequest =
                ((ServletServerHttpRequest) request).getServletRequest();

        /* Retrieve template variables */
        Map<String, String> uriTemplateVars =
                (Map<String, String>) origRequest
                    .getAttribute(
                        HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE);

        /* Put template variables into WebSocket session attributes */
        if (uriTemplateVars != null) {
            attributes.putAll(uriTemplateVars);
        }
        logger.info("In WebSocketConfig, UriTemplateHandshakeInterceptor, HandshakeInterceptor End.. ");

        return true;
    }

    @Override
    public void afterHandshake(ServerHttpRequest request,
            ServerHttpResponse response, WebSocketHandler wsHandler,
            Exception exception) {
        logger.info("In WebSocketConfig, afterHandshake.. ");
        response.setStatusCode(HttpStatus.SWITCHING_PROTOCOLS); 
    }
}
...