Почему SseService на основе Angular наблюдаемых работает только один раз, получает события, но производит первое - PullRequest
0 голосов
/ 05 мая 2020

Я использовал этот шаблон для создания службы ServerSentEvent: Angular и событий, отправленных сервером Вот код службы:

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 (каждую секунду или полсекунды) без причин для описания ошибки, кроме Type = error, EventPhase = 2. Но поступают события, которые генерируются сервером сразу после вставки в mongodb.

1 Ответ

0 голосов
/ 06 мая 2020

может быть несколько проблем

  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;
      }
    }

мой тест пример

...