Событие Websocket отслеживается только одним компонентом - PullRequest
0 голосов
/ 15 января 2019

У меня есть служба веб-сокетов в Angular7

import { environment } from './../../../environments/environment.prod';
import { Injectable } from '@angular/core';
import * as Rx from 'rxjs';
import {map} from 'rxjs/operators';
@Injectable()
export class WsService{
public wsMessages: Rx.Subject<any>;

public connect(url): Rx.Subject<MessageEvent> {
    if(!this.subject){
        this.subject = this.create(url);
        console.log("Websocket (Dashboard) successfully connected to : ", url);
    } 
    return this.subject;
}

private create(url): Rx.Subject<MessageEvent> {
    let ws = new WebSocket(
        url,
        [`Bearer`, `${this.token.substring(7)}`] 
        );
    let observable = Rx.Observable.create(
        (obs: Rx.Observer<MessageEvent>) => {
            ws.onmessage = obs.next.bind(obs);
            ws.onerror = obs.error.bind(obs);
            ws.onclose = obs.complete.bind(obs);
            return ws.close.bind(ws);
        }
    )

    let observer = {
        next: (data: Object) => {
            if(ws.readyState === WebSocket.OPEN) {
                ws.send(JSON.stringify(data));
            }
        }
    }

    return Rx.Subject.create(observer, observable);
}
private token: string;
constructor(){
   this.token = JSON.parse(localStorage.getItem('user')).token
    this.wsMessages = <Rx.Subject<any>>
    this.connect(`${environment.websocketUrl}/dashboard/ws`)
    .pipe(
        map((response: MessageEvent): any =>{
            let data = JSON.parse(response.data);
            return data;
        })
    )
}
private subject: Rx.Subject<MessageEvent>;

}

и у меня есть mulltiple компонент, который подписывается на wsMessages

 this.ws.wsMessages.subscribe(msg => {
    this.catchWebSocketEvents(msg)
    console.log("LeftBarSocket : ", msg);
  })

события печатаются только на одном компоненте, и мне нужно много компонентов для прослушивания этих событий ws.

1 Ответ

0 голосов
/ 16 января 2019

Хорошо, после небольшого прочтения этой темы я обнаружил, что есть функция share(), которая позволяет нескольким подписчикам совместно использовать источник.

решение здесь:

 const observable = Rx.Observable.create(
        (obs: Rx.Observer<MessageEvent>) => {
            this.ws.onmessage = obs.next.bind(obs);
            this.ws.onerror = obs.error.bind(obs);
            this.ws.onclose = obs.complete.bind(obs);
            return this.ws.close.bind(this.ws);
        }
    ).pipe(
        share()
    )

просто нужно добавить .pipe(share()) к наблюдаемой, создаваемой.

...