Reconnecting a websocket in Angular and rxjs?

后端 未结 3 737
醉梦人生
醉梦人生 2020-12-13 21:16

I have a ngrx/store (v2.2.2) and rxjs (v5.1.0) based application that listens to a web socket for incoming data using an observable. When I start the application I receive

相关标签:
3条回答
  • 2020-12-13 21:35

    This might not be the good answer but it's way too much for a comment.

    The problem might comes from your service :

    listenToTheSocket(): Observable<any> {
      this.websocket = new WebSocket(this.destination);
    
      this.websocket.onopen = () => {
        console.log("WebService Connected to " + this.destination);
      }
    
      return Observable.create(observer => {
        this.websocket.onmessage = (evt) => {
          observer.next(evt);
        };
      })
      .map(res => res.data)
      .share();
    }
    

    Do you think that you go multiple times in your component into the ngOnInit method?
    You should try to put a console.log into ngOnInit to be sure.

    Because if you do so, in your service you'll override the this.websocket with a new one.

    You should try something like that instead :

    @Injectable()
    export class MemberService implements OnInit {
    
      private websocket: any;
      private websocketSubject$ = new BehaviorSubject<any>();
      private websocket$ = this.websocketSubject$.asObservable();
    
      private destination = 'wss://notessensei.mybluemix.net/ws/time';
    
      constructor() { }
    
      ngOnInit() { }
    
      listenToTheSocket(): Observable<any> {
        if (this.websocket) {
          return this.websocket$;
        }
    
        this.websocket = new WebSocket(this.destination);
    
        this.websocket.onopen = () => console.log(`WebService Connected to ${this.destination}`);
    
        this.websocket.onmessage = (res) => this.websocketSubject$.next(res => res.data);
      }
    }
    

    The BehaviorSubject will send the last value if it receives an event before you subscribe to it. Plus, as it's a subject, no need to use the share operator.

    0 讨论(0)
  • 2020-12-13 21:42

    Actually there now is a WebsocketSubject in rxjs!

     import { webSocket } from 'rxjs/webSocket' // for RxJS 6, for v5 use Observable.webSocket
    
     let subject = webSocket('ws://localhost:8081');
     subject.subscribe(
        (msg) => console.log('message received: ' + msg),
        (err) => console.log(err),
        () => console.log('complete')
      );
     subject.next(JSON.stringify({ op: 'hello' }));
    

    It does handle reconnection when you resubscribe to a broken connection. So for example write this to reconnect:

    subject.retry().subscribe(...)
    

    See the docs for more info. Unfortunately the searchbox doesn't show the method, but you find it here:

    http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#static-method-webSocket

    that #-navigation is not working in my browser, so search for "webSocket" on that page.

    Source: http://reactivex.io/rxjs/file/es6/observable/dom/WebSocketSubject.js.html#lineNumber15

    0 讨论(0)
  • 2020-12-13 21:44

    For rxjs 6, websocket implementation.

    import { webSocket } from 'rxjs/websocket';
    let subject = webSocket('ws://localhost:8081');
    
    0 讨论(0)
提交回复
热议问题