【问题标题】:Spring Websocket with SockJS Connection Lost Issue带有 SockJS 连接丢失问题的 Spring Websocket
【发布时间】:2019-08-07 05:25:11
【问题描述】:

我正在使用 spring boot、angular cli 和 sockjs 开发一个 Web 应用程序。

WebSocket 实现:

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractSecurityWebSocketMessageBrokerConfigurer {

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

    @Override
    public void configureMessageBroker(MessageBrokerRegistry registry) {
        registry.enableSimpleBroker("/info", "/user", "/notif");
        registry.setApplicationDestinationPrefixes("/app");
    }
}

Angular websocket 实用程序实现:

注意:该类用于连接web socket和订阅例程!

@Injectable()
export class WebSocketUtil {

  stompClient = null;

  constructor() {
  }

  connect(subscribers: Subscriber[] = null) {
    let _this = this;
    let socket = new SockJS("https://localhost/ws");
    if (socket != null) {
      this.stompClient = Stomp.over(socket);
      if (this.stompClient != null) {
        console.log("Stomp client is connected!");

        let headers = {};
        headers["X-CSRF-TOKEN"] = ...;// csrf code

        this.stompClient.connect(headers, (frame) => {
          subscribers.forEach((subscriber) => {
            _this.stompClient.subscribe(subscriber.URL, subscriber.CALLBACK);
          });
        }, () => {
          console.log(_this.stompClient);
        });
      } else {
        throw {
          name: "StompClientNotRegistered",
          message: "Stomp client is not registered!"
        };
      }
    } else {
      throw {
        name: "SocketEstablishFailed",
        message: "Socket cannot be established!"
      };
    }
  }

  send(message) {
    this.stompClient.send(message.url, JSON.stringify(message.params));
  }
}

Angular 订阅者类实现:

注意:该类用于将订阅例程绑定到 stomp 客户端!

export class Subscriber {
  constructor(private url: string = "", private callback: any) {
  }

  get URL() {
    return this.url;
  }

  get CALLBACK() {
    return this.callback;
  }
}

WebsocketUtil 用法:

注意:这个sn-p代码是在view init阶段之后调用的。

this.webSocketUtil.connect([
      new Subscriber("/notif", function (data) {
        console.log(data);
      }),
      new Subscriber("/user", function (data) {
        console.log(data);
      })
    ]);

以上代码在网页浏览器(FF & chrome)控制台中导致以下错误:

注意:https://localhost/ws 可访问并返回“欢迎使用 SockJS!”消息。

【问题讨论】:

    标签: angular spring-boot spring-websocket sockjs


    【解决方案1】:

    最后,我解决了以下几点问题:

    1. 将适当的重写配置添加到 Apache2 配置 - 我会忽略它:(

      ...
      
      RewriteEngine On
      RewriteCond %{HTTP:Upgrade} =websocket [NC]
      RewriteRule ^/ws/(.*)       ws://localhost:8080/ws/$1 [P,L]    
      
      ...
      
    2. 在安全配置类中为/ws请求添加permit-all权限:

      @配置 @EnableWebSecurity 公共类 WebSecurityConfig 扩展 WebSecurityConfigurerAdapter {

      ...
      
      @Override
      protected void configure(HttpSecurity http) throws Exception {
          ...
          http.authorizeRequests().antMatchers("/ws/**").permitAll();
          ...
      }
      

      }

    3. 在 websocket 配置类中为 SimpTypes 添加 permit-all 权限:

      @配置 @EnableWebSocketMessageBroker 公共类 WebSocketConfig 扩展 AbstractSecurityWebSocketMessageBrokerConfigurer { ...

      @Override
      protected void configureInbound(MessageSecurityMetadataSourceRegistry messages) {
          messages.simpTypeMatchers(SimpMessageType.CONNECT, SimpMessageType.SUBSCRIBE, SimpMessageType.HEARTBEAT,
                  SimpMessageType.UNSUBSCRIBE, SimpMessageType.DISCONNECT).permitAll();
      }
      

      }

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-05-25
      • 2016-07-04
      • 2017-11-20
      • 2017-10-04
      • 2015-08-10
      • 2017-05-13
      • 2015-01-25
      • 2021-08-27
      相关资源
      最近更新 更多