Angular中如何手动关闭SSE连接?EventSource关闭方案求助
Angular手动关闭SSE连接方案
问题根源
当前代码中,Observable.create未定义订阅取消时的清理逻辑,组件调用unsubscribe()或takeUntil触发取消操作时,不会执行eventSource.close(),导致SSE连接持续存在。
解决方案
1. 修改Service,添加订阅清理逻辑
在Observable.create内部返回一个清理函数,当订阅被取消时自动关闭EventSource:
// service.ts public getServerSentEventsForTokenDisplay(url: string): Observable<any> { return Observable.create(observer => { const eventSource: EventSourcePolyfill = this.getEventSource(url); eventSource.addEventListener('XXX', (event: any) => { observer.next(event); }); eventSource.addEventListener('YYY', (event: any) => { observer.next(event); }); eventSource.addEventListener('Ack', (event: any) => { observer.next(event); }); eventSource.onerror = (error) => { eventSource.close(); this.ngZone.run(() => observer.next(error)); }; eventSource.onopen = (event) => { this.ngZone.run(() => observer.next(event)); }; // 新增:订阅取消时执行的清理函数 return () => { if (eventSource.readyState !== EventSource.CLOSED) { eventSource.close(); } }; }); }
2. 组件中实现手动关闭逻辑
组件可通过两种方式触发关闭:用户操作手动取消,或组件销毁时自动清理。
示例:添加手动关闭按钮的处理函数
// component.ts // 新增手动关闭方法 public manualCloseSSE(): void { if (this.tokenDisplaySubscription) { this.tokenDisplaySubscription.unsubscribe(); this.tokenDisplaySubscription = null; // 避免重复取消 // 重置加载状态 this.isWaitingTokensLoading = false; this.isTokenDisplayLoading = false; } } // 原有销毁逻辑保持不变 ngOnDestroy() { this.ngUnsubscribe.next(); this.ngUnsubscribe.unsubscribe(); if(this.tokenDisplaySubscription) { this.tokenDisplaySubscription.unsubscribe(); } }
在模板中添加触发按钮:
<button (click)="manualCloseSSE()">关闭SSE连接</button>
关键说明
- 清理函数会在以下场景自动触发:组件销毁时的
unsubscribe、takeUntil触发取消、手动调用unsubscribe()。 - 判断
readyState是为了避免重复关闭已断开的连接。 - 确保EventSource实例被正确关闭,释放服务器端资源。
内容的提问来源于stack exchange,提问作者Chhaya Tiwari
相关产品推荐
相关产品推荐

