angular - 带有 SockJS 连接丢失问题的 Spring Websocket
问题描述
我正在使用 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 用法:
注意:这段代码是在视图初始化阶段之后调用的。
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!” 信息。
解决方案
最后,我解决了以下几点的问题:
将适当的重写配置添加到 Apache2 配置中-我忽略了它:(
... RewriteEngine On RewriteCond %{HTTP:Upgrade} =websocket [NC] RewriteRule ^/ws/(.*) ws://localhost:8080/ws/$1 [P,L] ...
在安全配置类中为/ws请求添加 permit-all 权限:
@Configuration @EnableWebSecurity 公共类 WebSecurityConfig 扩展 WebSecurityConfigurerAdapter {
... @Override protected void configure(HttpSecurity http) throws Exception { ... http.authorizeRequests().antMatchers("/ws/**").permitAll(); ... }
}
在 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(); }
}
推荐阅读
- sqlite - 打开与 sqlite 数据库的连接会导致文件无法被删除
- angular - 选项未显示在primeng下拉列表中?
- ruby - 使用 page.find 时 Site_Prism 未找到 POM 元素
- powershell - 使用 PowerShell 为 IIS_IUSRS 分配文件访问权限
- javascript - Google App Engine Standard Java 在部署时使用 Unicode 字符破坏代码
- javascript - 什么是 n ,如何在 Javascript 滑块图像的脚本中定义函数
- wait - 为什么在类中通知时不抛出 IllegalMonitorStateException
- r - 使用函数均值 [R] 时出现“参数不是数字或逻辑:返回 NA”错误
- xcode - Xcode source control won't commit
- python - 在训练时测量决策树的准确性