【问题标题】:Error during WebSocket handshake: Unexpected response code: 200 In Jhipster applicationWebSocket 握手期间出错:意外的响应代码:200 在 Jhipster 应用程序中
【发布时间】:2021-02-22 04:46:12
【问题描述】:

我正在尝试在使用 Java spring 和 Angular 8 构建的现有 Jhipster 应用程序中连接到 websocket。在创建项目时,我没有选择 websocket 选项,现在需要实现项目中的 websockets。我从“https://www.jhipster.tech/using-websockets/”获得帮助并尝试实施相同的解决方案,但我收到握手失败消息。 我在 websockets 中使用 STOMP 和 sockJS。 请让我知道握手失败的原因。

这里是 websocket configuration.java 文件。


import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer;
import org.springframework.web.socket.server.support.DefaultHandshakeHandler;

import hr.nic.vc.security.AuthoritiesConstants;

import java.security.Principal;

import org.springframework.http.server.*;

import java.util.*;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.server.*;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.security.authentication.AnonymousAuthenticationToken;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.config.annotation.*;
import org.springframework.web.socket.server.HandshakeInterceptor;
import org.springframework.web.socket.server.support.DefaultHandshakeHandler;

@Configuration
@EnableWebSocketMessageBroker
public class WebsocketConfiguration implements WebSocketMessageBrokerConfigurer {

  @Override
  public void configureMessageBroker(MessageBrokerRegistry config)
  {
    config.enableSimpleBroker("/topic");
    //config.setApplicationDestinationPrefixes("/app");
  }

  @Override
  public void registerStompEndpoints(StompEndpointRegistry
   registry) {
    registry.addEndpoint("/websocket/blog").setHandshakeHandler(defaultHandshakeHandler())
        .setAllowedOrigins("*").withSockJS();
  }
  
  @Bean
  public HandshakeInterceptor httpSessionHandshakeInterceptor() {
      return new HandshakeInterceptor() {

          @Override
          public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Map<String, Object> attributes) throws Exception {
              if (request instanceof ServletServerHttpRequest) {
                  ServletServerHttpRequest servletRequest = (ServletServerHttpRequest) request;
                  attributes.put(IP_ADDRESS, servletRequest.getRemoteAddress());
              }
              return true;
          }

          @Override
          public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Exception exception) {

          }
      };
  }

  private DefaultHandshakeHandler defaultHandshakeHandler() {
      return new DefaultHandshakeHandler() {
          @Override
          protected Principal determineUser(ServerHttpRequest request, WebSocketHandler wsHandler, Map<String, Object> attributes) {
              Principal principal = request.getPrincipal();
              if (principal == null) {
                  Collection<SimpleGrantedAuthority> authorities = new ArrayList<>();
                  authorities.add(new SimpleGrantedAuthority(AuthoritiesConstants.ANONYMOUS));
                  principal = new AnonymousAuthenticationToken("WebsocketConfiguration", "anonymous", authorities);
              }
              return principal;
          }
      };
  }
  
}

这是 websocket 安全文件。

public class WebsocketSecurityConfiguration extends AbstractSecurityWebSocketMessageBrokerConfigurer {

    @Override
      protected void configureInbound(MessageSecurityMetadataSourceRegistry messages)
      {
        messages.nullDestMatcher().authenticated().simpDestMatchers("/topic/blog")
            .authenticated()
            // matches any destination that starts with /topic/
            // (i.e. cannot send messages directly to /topic/)
            // (i.e. can’t subscribe to /topic/messages/* to get messages which is sent to
            // /topic/messages-user)
            .simpDestMatchers("/topic/**").authenticated();
            // message types other than MESSAGE and SUBSCRIBE
            //.simpTypeMatchers(SimpMessageType.MESSAGE, SimpMessageType.SUBSCRIBE).denyAll()
            // catch all
            //.anyMessage().denyAll();
      }
    /**
     * Disables CSRF for Websockets.
     */
    @Override
    protected boolean sameOriginDisabled() {
        return true;
    }
}

这里是连接websocket认证后调用的connect方法。

connect():void {
    console.log("connect called"); //eslint-disable-line
    // build absolute path, websocket doesn't fail during deploying with a context path
    let url = '/websocket/blog';
    url = this.location.prepareExternalUrl(url);
    const authToken = this.authServerProvider.getToken();
    if (authToken) {
      url += '?access_token=' + authToken;
    }
    const socket = new SockJS(url);
    this.stompClient = Stomp.over(socket);
    const headers = {};
    this.stompClient.connect(headers, () => {
        console.log("this is inside stompclient connect connect"); //eslint-disable-line
      this.stompClient.subscribe('/topic/blog', data => {
          console.log("This inside subscription"); //eslint-disable-line
        this.listenerObserver.next(JSON.parse(data.body));
      });
    });
  }
}

授权令牌以正确的值传递。因此授权没有错误。 请让我知道是否需要其他任何内容。 我在这一点上卡了很长时间。

错误:

WebSocket connection to 'ws://localhost:8080/websocket/blog/587/mklduqvp/websocket?access_token=eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJoYXJkZWVwc2h1a2xhMDhAbmljLmluIiwiYXV0aCI6IlJPTEVfRU1QTE9ZRUUiLCJleHAiOjE2MDUyNDUwNjd9.DJ2HITaVAiaphd2yg3yPAiLrLI4n8MjszjBasC3zOHrC-73mFdltDPEYHihY16VzPv0rh6EYLj84zCBv37TDNA' failed: Error during WebSocket handshake: Unexpected response code: 200

【问题讨论】:

  • 您是否尝试过生成与旧项目相同设置的新项目并复制配置?
  • 是的,我试过了。仍然没有运气。与上述相同的错误。
  • 新生成的项目工作正常。我试图将 websocket 配置添加到现有项目中。我也更新了错误。请看一下
  • 新旧项目的Jhipster版本相同。是的,我检查了服务器端日志,没有错误,只有客户端显示此错误。我没有在调试器中运行服务器,因为这两个项目完全不同。
  • 调试器将向您显示消息代理中的执行,这不是您的代码,因此两个项目之间是相同的,只是它的初始化应该不同并触发不同的行为。对于org.springframework.web.socket,服务器日志可能不在 DEBUG 级别,因此您看不到comapre 发生了什么。

标签: spring-boot websocket jhipster stomp sockjs


【解决方案1】:

在你的 DefaultHandshakeHandler 中,你可以尝试注释 @Bean 并设置为 public。

@Bean
public DefaultHandshakeHandler defaultHandshakeHandler() {

【讨论】:

  • 感谢您的回答,但我已经尝试过了。仍然出现同样的错误。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-15
  • 1970-01-01
  • 2014-05-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多