Подключение пружины при установлении соединения застряло при «открытии соединения» - PullRequest
0 голосов
/ 29 января 2020

Я использую spring-boot-websocket (spring-boot версия 1.5.10) в моем проекте. Я настроил его следующим образом:

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig extends WebSocketMessageBrokerConfigurationSupport
        implements WebSocketMessageBrokerConfigurer {

    @Value( "${rabbitmq.host}" )
    private String rabbitmqHost;
    @Value( "${rabbitmq.stomp.port}" )
    private int rabbitmqStompPort;
    @Value( "${rabbitmq.username}" )
    private String rabbitmqUserName;
    @Value( "${rabbitmq.password}" )
    private String rabbitmqPassword;

    @Override
    public void configureMessageBroker( MessageBrokerRegistry registry )
    {
        registry.enableStompBrokerRelay("/topic", "/queue").setRelayHost(rabbitmqHost).setRelayPort(rabbitmqStompPort)
                .setSystemLogin(rabbitmqUserName).setSystemPasscode(rabbitmqPassword);
        registry.setApplicationDestinationPrefixes("/app");
    }

    @Override
    public void registerStompEndpoints( StompEndpointRegistry stompEndpointRegistry )
    {
        stompEndpointRegistry.addEndpoint("/ws").setAllowedOrigins("*").withSockJS();
    }

    @Bean
    @Override
    public WebSocketHandler subProtocolWebSocketHandler()
    {
        return new CustomSubProtocolWebSocketHandler(clientInboundChannel(), clientOutboundChannel());
    }

    @Override
    public void configureWebSocketTransport( WebSocketTransportRegistration registry )
    {
        super.configureWebSocketTransport(registry);
    }

    @Override
    public boolean configureMessageConverters( List<MessageConverter> messageConverters )
    {
        return super.configureMessageConverters(messageConverters);
    }

    @Override
    public void configureClientInboundChannel( ChannelRegistration registration )
    {
        super.configureClientInboundChannel(registration);
    }

    @Override
    public void configureClientOutboundChannel( ChannelRegistration registration )
    {
        super.configureClientOutboundChannel(registration);
    }

    @Override
    public void addArgumentResolvers( List<HandlerMethodArgumentResolver> argumentResolvers )
    {
        super.addArgumentResolvers(argumentResolvers);
    }

    @Override
    public void addReturnValueHandlers( List<HandlerMethodReturnValueHandler> returnValueHandlers )
    {
        super.addReturnValueHandlers(returnValueHandlers);
    }

}

public class CustomSubProtocolWebSocketHandler extends SubProtocolWebSocketHandler {

    private static final Logger LOGGER = LoggerFactory.getLogger(CustomSubProtocolWebSocketHandler.class);

    @Autowired
    private UserCommons userCommons;

    CustomSubProtocolWebSocketHandler(MessageChannel clientInboundChannel,
                                      SubscribableChannel clientOutboundChannel) {
        super(clientInboundChannel, clientOutboundChannel);
    }

    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        LOGGER.info("************************************************************************************************************************New webSocket connection was established: {}", session);
        String token = session.getUri().getQuery().replace("token=", "");
        try
        {
            String user = Jwts.parser().setSigningKey(TokenConstant.SECRET)
                    .parseClaimsJws(token.replace(TokenConstant.TOKEN_PREFIX, "")).getBody().getSubject();
            Optional<UserModel> userModelOptional = userCommons.getUserByEmail(user);
            if( !userModelOptional.isPresent() )
            {
                LOGGER.error(
                        "************************************************************************************************************************Invalid token is passed with web socket request");
                throw new DataException(GeneralConstants.EXCEPTION, "Invalid user", HttpStatus.BAD_REQUEST);
            }
        }
        catch( Exception e )
        {
            LOGGER.error(GeneralConstants.ERROR, e);
        }
        super.afterConnectionEstablished(session);
    }

    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception {
        LOGGER.error("************************************************************************************************************************webSocket connection was closed");
        LOGGER.error("Reason for closure {} Session: {} ", closeStatus.getReason(),session.getId() );
        super.afterConnectionClosed(session, closeStatus);
    }

    @Override
    public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {

        LOGGER.error("************************************************************************************************************************Connection closed unexpectedly");
        LOGGER.error(GeneralConstants.ERROR, exception);
        super.handleTransportError(session, exception);
    }
}

На стороне клиента я создаю объект SockJS для установления sh соединения,

let url = `/ws?token=${localStorage.getItem("access_token")}`;
        // Web Socket connection
        /* eslint-disable */
        let sockJS = new SockJS(url);
        let stompClient = Stomp.over(sockJS);
        debugger
        this.setState({
            stompObject : stompClient,
        });

Но соединение не устанавливается постоянно, в большинстве случаев он застревает на Opening the connection, в журнале бэкэнда я вижу, как устанавливается соединение и создается сеанс. Но в консоли браузера я вижу отправку сообщения на сервер на стороне клиента, но сервер не подтверждает сообщение.

enter image description here

enter image description here

Иногда, когда я обновляю sh браузер 10-15 раз, соединение устанавливается успешно. Есть ли ошибка в моей конфигурации?

Спасибо.

1 Ответ

0 голосов
/ 29 января 2020

Учитывая, что вы можете "нажать refre sh 10 или 15 раз, а затем получить соединение", мне интересно, если вы имеете дело с вопросом повара ie? Я знаю, что Chrome славится такими вещами. В любом случае закройте все браузеры windows и остановите браузер, затем запустите браузер и скажите, чтобы он очистил историю просмотров и затем попытался установить соединение. Кроме того, убедитесь, что вы прочитали версию документации по Spring-Boot для той версии Spring-Boot, которую вы фактически используете, а также укажите версию SB в своих вопросах и при поиске ответов.

...