web-dev-qa-db-ja.com

Angular2 / Websocket:着信WebSocketメッセージのオブザーバブルを返す方法

Angular2を使用して、WebSocketの受信メッセージを受信し、受信したメッセージに基づいてWebページを更新します。現在、ダミーのエコーWebSocketサービスを使用しており、これを置き換えます。

私の理解では、WebSocketメッセージを受信する関数は、Webページを更新するハンドラーによってサブスクライブされたオブザーバブルを返す必要があります。しかし、オブザーバブルを返す方法がわかりません。

コードスニペットは以下に添付されています。 MonitorServiceはWebSocket接続を作成し、受信したメッセージを含むオブザーバブルを返します。

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

}

以下は、上から返されたオブザーバブルをサブスクライブし、それに応じてWebページを更新する別のコンポーネントです。

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

今、私はブラウザコンソールでこのエラーに遭遇していますTypeError: this._subscribe is not a function

10
Bing Lu

plunker に配置し、Websocketエンドポイントにメッセージを送信するための関数を追加しました。重要な編集は次のとおりです。

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

更新
コメントで述べたように、より良い代替方法はObservable.fromEvent()を使用することです。

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

プランカーの例 for Observable.fromEvent();

また、WebSocketSubjectを使用してそれを行うこともできますが、まだ準備ができていないようです(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));
} 
_

プランカーの例

ソケットからonMessageデータを取得します。

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

}
0
Ashish Gupta