2016-04-25 21 views
7

Utilizzerò Angular2 per ricevere i messaggi in arrivo Websocket e aggiornare una pagina Web in base a tali messaggi ricevuti. In questo momento, sto usando un servizio di websocket echo fittizio e lo sostituirò.Angular2/Websocket: come restituire un osservabile per i messaggi Websocket in entrata

Dalla mia comprensione, la funzione che riceve i messaggi di websocket deve restituire un osservabile che è sottoscritto da un gestore che aggiornerà la pagina web. Ma non riesco a capire come restituire un osservabile.

Lo snippet di codice è riportato di seguito. Lo MonitorService crea una connessione web socket e restituisce un osservabile contenente i messaggi ricevuti.

@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(); 
    } 

} 

Di seguito è un altro componente che sottoscrive l'osservabile restituito da sopra e aggiorna le pagine Web in modo corrispondente.

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

Ora, sto correndo in questo errore nella console del browser TypeError: this._subscribe is not a function

risposta

8

ho messo su un plunker e ho aggiunto una funzione per l'invio del messaggio al punto finale websocket. Ecco la modifica importante:

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

Aggiornamento
Come lei ha ricordato nel tuo commento, un modo migliore alternativa è quella di utilizzare Observable.fromEvent()

websocket = new WebSocket("ws://echo.websocket.org/"); 
public GetInstanceStatus(): Observable<Event>{ 
    return Observable.fromEvent(this.websocket,'message'); 
} 

plunker example per Observable.fromEvent();

Inoltre, è possibile farlo utilizzando WebSocketSubject, anche se, non sembra come se fosse ancora pronto (come di 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)); 
} 

plunker example

+0

Grazie! E si scopre che ritornare osservabile come questo funziona anche con 'return Observable.fromEvent (websocket, 'message');' Hai qualche idea sulle loro differenze? –

+0

@BingLu Sono quasi la stessa cosa. Il modo 'fromEvent' è solo un wrapper per l'evento, che è quello che ho fatto nella mia risposta. Dubito che ci sia qualche differenza. Ma è comunque un modo migliore della mia risposta: D. Aggiornerò la mia risposta per includerla. Grazie – Abdulrahman

+0

@Abdulrahman So che è stato molto tempo fa, ma mi chiedo se è possibile aggiornare il Plunker per usare 'fromEvent'. Btw, non dovrebbe essere usato 'WebSocketSubject' per lo streaming dei dati? (Mi sto chiedendo, sono nuovo di websockets). – brians69

0

Get onMessage dati da presa .

import { Injectable } from '@angular/core'; 
import {Observable} from 'rxjs/Rx'; 


@Injectable() 

export class HpmaDashboardService { 
private socketUrl: any = 'ws://127.0.0.0/util/test/dataserver/ws'; 
private websocket: any;  

public GetAllInstanceStatus(objStr): Observable<any> { 
     this.websocket = new WebSocket(this.socketUrl); 
     this.websocket.onopen = (evt) => { 
     this.websocket.send(JSON.stringify(objStr)); 
     }; 
     return Observable.create(observer => { 
     this.websocket.onmessage = (evt) => { 
      observer.next(evt); 
     }; 
     }).map(res => res.data).share(); 
} 

**Get only single mesage from socket.** 

    public GetSingleInstanceStatus(objStr): Observable<any> { 
     this.websocket = new WebSocket(this.socketUrl); 
     this.websocket.onopen = (evt) => { 
     this.websocket.send(JSON.stringify(objStr)); 
     }; 
     return Observable.create(observer => { 
     this.websocket.onmessage = (evt) => { 
      observer.next(evt); 
      this.websocket.close(); 
     }; 
     }).map(res => res.data).share(); 
    } 

} 
Problemi correlati