Mit RxJs und Winkel 2 im Hinblick auf den Umgang mit server-sent events
Ich versuche, Anzeige von server-sent-events emittierten Werte in eine eckige 2 /RxJs app.
Backend versendet regelmäßig an einzelnen strings an den client über das server-sent-events.
Ich bin mir nicht sicher, wie man mit der abgerufene Werte für die Winkel-2/RxJs Seite.
Hier ist mein client (ng-Komponente):
import {Component, OnInit} from 'angular2/core';
import {Http, Response} from 'angular2/http';
import 'rxjs/Rx';
import {Observable} from 'rxjs/Observable';
@Component({
selector: 'my-app',
template: `<h1>My second Angular 2 App</h1>
<ul>
<li *ngFor="#s of someStrings | async">
a string: {{ s }}
</li>
</ul>
`
})
export class AppComponent implements OnInit {
constructor(private http:Http) {
}
errorMessage:string;
someStrings:string[];
ngOnInit() {
this.getSomeStrings()
.subscribe(
aString => this.someStrings.push(aString),
error => this.errorMessage = <any>error);
}
private getSomeStrings():Observable<string> {
return this.http.get('interval-sse-observable')
.map(this.extractData)
.catch(this.handleError);
}
private extractData(res:Response) {
if (res.status < 200 || res.status >= 300) {
throw new Error('Bad response status: ' + res.status);
}
let body = res.json();
return body || {};
}
private handleError(error:any) {
//In a real world app, we might send the error to remote logging infrastructure
let errMsg = error.message || 'Server error';
console.error(errMsg); //log to console instead
return Observable.throw(errMsg);
}
}
Backend-Methode ist wie folgt (und verwendet RxJava):
@ResponseStatus(HttpStatus.OK)
@RequestMapping(method = RequestMethod.GET, path = "interval-sse-observable")
public SseEmitter tickSseObservable() {
return RxResponse.sse(
Observable.interval(5, TimeUnit.SECONDS, Schedulers.io())
.map(tick -> randomUUID().toString())
);
}
Mir ist gerade aufgefallen, dass die app hängt an der Anfrage und es wird nichts angezeigt auf der Seite.
Ich vermute es ist ein Problem mit meinem map-Methode, D. H. .map(this.extractData)
.
Möchte ich nur hinzufügen, die eingehende strings in das array und die Anzeige, dass array in der Vorlage, die aktualisiert werden würde, als die Streicher.
Kann bitte jemand helfen?
Bearbeiten: Hier ist eine funktionierende Lösung (Dank an Thierry, Antwort unten):
import {Component, OnInit} from 'angular2/core';
import 'rxjs/Rx';
@Component({
selector: 'my-app',
template: `<h1>My second Angular 2 App</h1>
<ul>
<li *ngFor="#s of someStrings">
a string: {{ s }}
</li>
</ul>
`
})
export class AppComponent implements OnInit {
someStrings:string[] = [];
ngOnInit() {
let source = new EventSource('/interval-sse-observable');
source.addEventListener('message', aString => this.someStrings.push(aString.data), false);
}
}
- Können Sie bitte lassen Sie mich wissen, wenn Sie waren in der Lage, diese arbeiten mit Winkel-4? Ich benutze import { Komponente, OnInit } von '@eckig/core', und es nicht finden EventSource-Klasse. Können Sie bitte lassen Sie mich wissen, wenn Sie hve installiert eine beliebige andere benutzerdefinierte Paket? Würde schätzen, wenn Sie teilen können Sie den vollständigen code in github oder so, für die Referenz. Danke.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Können Sie nicht verwenden, die Http-Klasse von Angular2 zu handhaben, server-side-events, da es basiert auf dem XHR-Objekt.
Könnten Sie nutzen die EventSource-Objekt:
Finden Sie in diesen Artikeln:
Hier ist ein funktionierendes Beispiel :
SseService
AppComponent
Hinzufügen Thierry ' s Antwort, Standardmäßig wird der event-Typ ist "Botschaft". Aber der event-Typ kann alles sein, wie ('chat', 'log', usw.) basierend auf der server-Seite Implementierung.
In meinem Fall, die ersten beiden Veranstaltungen aus dem server waren, 'Nachricht' und der rest von Ihnen wurden 'log'. Mein code sieht wie unten
var source = new EventSource('/...');
source.addListener('message', message => {
(...)
});
source.addListener('log', log => {
(...)
});