为什么基于Angular observable的SseService只工作一次,接收事件但产生第一个事件



我使用此模式创建ServerSentEvent服务:Angular和Server Sent Events这是服务代码:

import { Injectable, NgZone } from "@angular/core";
import { Observable } from "rxjs";
@Injectable({
providedIn: "root"
})
export class SseService {
constructor(private _zone: NgZone) { }
getServerSentEvent(url: string): Observable<any> {
return Observable.create(observer => {
const eventSource = this.getEventSource(url);
eventSource.onmessage = event => {
this._zone.run(() => {
observer.next(event.data);
console.log(event); // Here I see every received  event
});
};
eventSource.onerror = error => {
this._zone.run(() => {
observer.error(error);
console.log(error);
});
};
// return () => eventSource.close();
});
}
private getEventSource(url: string): EventSource {
return new EventSource(url);
}
}

然后我在主组件中调用这个ss事件流:

ngOnInit() { //This subscribe works just for the first event no more
this.sseService.getServerSentEvent("http://localhost:8080/ssevents")
.subscribe(
data => {
this.eventmessage = data;
},
error => this.error = error
);
// But direct next EventSource onmessage() call works here: 
this.source = new EventSource("http://localhost:8080/ssevents");
this.source.onmessage = event => {
this.zone.run(() => {
this.eventmessage = event.data;
console.log(event);
});
};
this.source.onerror = error => {
this.zone.run(() => {
this.error = error.type;
console.log(error);
});
};
}

为什么sseservice中的这种内部可观察结果没有作品只是第一个。所以我需要使用第二种选择,但我接收永久错误EventTarget(每秒或半秒(没有理由错误描述,类型=错误,EventPhase=2除外。但是接收事件,这些事件仅由服务器生成插入mongodb之后。

可能有几个问题

  1. 尝试addEventListener而不是onmessage
  2. 检查消息格式链接
  3. 浏览器可以断开连接,若你们有移动然后6连接到相同的主机链接

所以当你在测试时,你可以很快超过

@Injectable()
export class SseService {
private eventSource: EventSource;
constructor(private zone: NgZone) {}
getServerSentEvent(url: string): Observable<MessageEvent> {
return Observable.create(observer => {
const eventSource = this.getEventSource(url);
eventSource.onopen = (ev) => {
console.log('Connection to server opened.', ev);
};
eventSource.onerror = (ev) => {
console.log('EventSource failed.', ev);
};
eventSource.addEventListener('message', event => {
this.zone.run(() => {
observer.next(event);
});
});
});
}
private getEventSource(url: string): EventSource {
if (this.eventSource) {
console.log('EventSource closed.');
this.eventSource.close();
}
this.eventSource = new EventSource(url);
return this.eventSource;
}
}

我的测试示例

相关内容

  • 没有找到相关文章

最新更新