繁体   English   中英

带有SockJS连接的Spring Websocket丢失问题

[英]Spring Websocket with SockJS Connection Lost Issue

我正在使用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 util实现:

注意:此类用于连接Web套接字和订阅例程!

@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用法:

注意:在视图初始化阶段之后调用此代码片段。

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

上面的代码导致Web浏览器(FF和chrome)控制台出现以下错误:

浏览器错误!

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

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

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

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

    @Configuration @EnableWebSecurity公共类WebSecurityConfig扩展WebSecurityConfigurerAdapter {

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

    }

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

    @Configuration @EnableWebSocketMessageBroker公共类WebSocketConfig扩展了AbstractSecurityWebSocketMessageBrokerConfigurer {...

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

    }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM