2016-04-25 2 views
7

Я собираюсь использовать Angular2 для приема входящих сообщений в сети и обновления веб-страницы на основе полученных сообщений. Прямо сейчас, я использую фиктивный сервис echo websocket и заменяю его.Angular2/Websocket: как вернуть наблюдаемый для входящих сообщений веб-памяти

С моей точки зрения, функция, получающая сообщения веб-рассылки, должна возвращать наблюдаемое, которое подписывается обработчиком, который обновит веб-страницу. Но я не могу понять, как вернуть наблюдаемое.

Ниже приведен фрагмент кода. 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(); 
    } 

} 

Ниже приведен еще один компонент, который подписывается на наблюдаемый, возвращенный сверху, и соответственно обновляет веб-страницы.

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

ответ

8

Я положил его на 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(); 
} 

Update
Как вы упомянули в своем комментарии, лучший альтернативный способ заключается в использовании Observable.fromEvent()

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

plunker example для 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)); 
} 

plunker example

+0

Спасибо! И, оказывается, что возвращаемое наблюдаемое подобное также работает 'return Observable.fromEvent (websocket, 'message');' Есть ли у вас какие-либо идеи об их различиях? –

+0

@BingLu Они почти одинаковы. Путь 'fromEvent' - это просто оболочка для события, что я и сделал в своем ответе. Я сомневаюсь, что есть какая-то разница. Но, тем не менее, это лучший способ, чем мой ответ: D. Я обновлю свой ответ, чтобы включить его. Спасибо – Abdulrahman

+0

@Abdulrahman Я знаю, что это было давно, но мне интересно, можете ли вы обновить Plunker, чтобы использовать 'fromEvent'. Btw, не следует использовать 'WebSocketSubject' для потоковой передачи данных? (Мне просто интересно, я новичок в websockets). – brians69

0

Получить 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(); 
    } 

} 
Смежные вопросы