在我们的Angular websocket服务中,为了告诉后端我们还在听,我们必须发送一种保持活动信号。
以下是我们的进展方式:
@Injectable()
export class WebsocketService {
private ws: CustomWebSocket;
constructor() {
this.ws = new CustomWebSocket('ws://localhost');
this.ws.onOpened(() => {
console.info('WS connected');
this.keepAlive();
});
}
public keepAlive() {
Observable.interval(10000).subscribe((tick: number) => this.ws.send('keep-alive'));
}
}
1 /此服务注入我们的主app.module.ts。我们是否必须手动取消订阅间隔,或者允许这种无限可观测序列是否安全?
2 /作为一般性问题,如果我们必须取消订阅,由于订阅是在服务范围内,这样做的正确方法是什么?我们没有ngOnDestroy
生命周期钩子,所以如何正确地做到这一点?
答案 0 :(得分:3)
我们是否必须手动取消订阅时间间隔,或者允许这种无限可观察序列是安全的?
通常情况下,如果服务意味着应用程序的整个生命周期都存在,那么您就不必费心了,因为浏览器会为您清理。但是,有一些事情需要考虑:
遵循最少惊喜的原则,服务应该在销毁后自行清理,所以我绝对会建议这样做。
我们没有ngOnDestroy生命周期钩子,所以如何正确地做到这一点?
这是一个流行的声明,但这是错误的。 ngOnDestroy
也被称为服务。直接从the docs:
销毁指令,管道或服务时调用的生命周期钩子。
所以你绝对可以这样做:
@Injectable()
export class WebsocketService implements OnDestroy {
private ws: CustomWebSocket;
private destroy$ = new Subject();
constructor() {
this.ws = new CustomWebSocket('ws://localhost');
this.ws.onOpened(() => {
console.info('WS connected');
this.keepAlive();
});
}
public keepAlive() {
Observable.interval(10000)
.takeUntil(this.destroy$)
.subscribe((tick: number) => this.ws.send('keep-alive'));
}
public ngOnDestroy() {
this.destroy$.next();
this.destroy$.complete();
}
}
答案 1 :(得分:0)
该服务的问题在于,您没有取消订阅的销毁方法,并且确实需要取消订阅,只有http请求是自动关闭的(http服务会为您执行此操作)。
我希望你的WebsocketService向你的主应用程序组件返回一个冷的observable。
在主应用组件中为您的observable创建占位符 IE:ngUnsubscribe:Subject = new Subject();
从您的服务订阅您的observable。 IE:WebsocketService.keepAlive()。takeUntil(this.ngUnsubscribe).subscribe();
在主应用程序组件的onDestroy事件中,我将调用this.ngUnsubscribe.next(); this.ngUnsubscribe.complete();