Angular2/Websocket: how to return an observable for incoming websocket messages
I put it on a plunker and I added a function for sending message to the Websocket endpoint. Here is the important edit:
public GetInstanceStatus(): Observable<any>{
this.websocket = new WebSocket("ws://echo.websocket.org/"); //dummy echo websocket service
this.websocket.onopen = (evt) => {
this.websocket.send("Hello World");
};
return Observable.create(observer=>{
this.websocket.onmessage = (evt) => {
observer.next(evt);
};
})
.share();
}
Update
As you mentioned in your comment, a better alternative way is to use Observable.fromEvent()
websocket = new WebSocket("ws://echo.websocket.org/");
public GetInstanceStatus(): Observable<Event>{
return Observable.fromEvent(this.websocket,'message');
}
plunker example for Observable.fromEvent()
;
Also, you can do it using WebSocketSubject
, although, it doesn't look like it's ready yet (as of rc.4):
constructor(){
this.websocket = WebSocketSubject.create("ws://echo.websocket.org/");
}
public sendMessage(text:string){
let msg = {msg:text};
this.websocket.next(JSON.stringify(msg));
}
Related videos on Youtube
Bing Lu
Updated on July 13, 2022Comments
-
Bing Lu almost 2 years
I'm going to use Angular2 to receive websocket incoming messages and update a webpage based on those received messages. Right now, I'm using a dummy echo websocket service and will replace it.
From my understanding, the function which receive websocket messages has to return an observable that is subscribed by a handler who will update the webpage. But I can't figure out how to return an observable.
Code snippet is attached below. The
MonitorService
creates a websocket connection and return an observable containing the received messages.@Injectable() export class MonitorService { private actionUrl: string; private headers: Headers; private websocket: any; private receivedMsg: any; constructor(private http: Http, private configuration: AppConfiguration) { this.actionUrl = configuration.BaseUrl + 'monitor/'; this.headers = new Headers(); this.headers.append('Content-Type', 'application/json'); this.headers.append('Accept', 'application/json'); } public GetInstanceStatus = (): Observable<Response> => { this.websocket = new WebSocket("ws://echo.websocket.org/"); //dummy echo websocket service this.websocket.onopen = (evt) => { this.websocket.send("Hello World"); }; this.websocket.onmessage = (evt) => { this.receivedMsg = evt; }; return new Observable(this.receivedMsg).share(); } }
Below is another component which subscribes to the observable returned from above and updates webpages correspondingly.
export class InstanceListComponent { private instanceStatus: boolean private instanceName: string private instanceIcon: string constructor(private monitor: MonitorService) { this.monitor.GetInstanceStatus().subscribe((result) => { this.setInstanceProperties(result); }); } setInstanceProperties(res:any) { this.instanceName = res.Instance.toUpperCase(); this.instanceStatus = res.Status; if (res.Status == true) { this.instanceIcon = "images/icon/healthy.svg#Layer_1"; } else { this.instanceIcon = "images/icon/cancel.svg#cancel"; } } }
Now, I'm running into this error in the browser console
TypeError: this._subscribe is not a function