skip to Main Content

The situation is as follows:
I have a websocket for communication between app and server. If the websocket were to break I would like to enable backup long polling until the websocket becomes active again.

I thought of creating a Signal boolean that changes state based on the connection/disconnection of the WS. If the WS is active I set the signal to true otherwise to false.

 WSStatus = signal(false);
 WS is up: this.WSStatus(true)
 WS go down: this.WSStatus(false)

I thought about doing something like this, but takeUntil waits for an Observable and I was unable to replace the Signal operation with an Observable

 this.startPolling(5000).pipe(takeUntil(!this.WSStatus())).subscribe()
 startPolling(interval: number = 5000): Observable<string> {
  
    return timer(0, interval)
      .pipe(
        switchMap( () => { return this.myHttpRequest() })
      );
  }

2

Answers


  1. Chosen as BEST ANSWER

    The purpose of the code is to have a backup to the websocket in case of problems, so when it is NOT active I run a long time polling on http protocol until the websocket becomes active again

    This is the solution I found:

    properties:

    pollingDone = signal(false)
    private timerDone$ = new Subject<boolean>();
    

    ws connection:

    ...
    openObserver: {
      next: (event) => {
        this.pollingDone.set(true);
      }
    },
    closeObserver: {
      next: (event) => {
        this.pollingDone.set(false);
      }
    }
    ...
    

    constructor

    effect( () => {
      this.timerDone$.next(this.pollingDone())
      if(this.pollingDone() === false) {
        this.startPolling(5000).subscribe(val => this.store.dispatch(TablePageActions.load()))
      }
    })
    

    methods

    startPolling(interval: number = 5000): Observable<any> {
      return timer(0, interval)
      .pipe(
        takeUntil(this.timerDone$)
      )
    }
    

    Maybe it's not stylistic, I had difficulty defining an observable boolean accepted by the takeUntil, anyway it seems the goal was achieved. I tried to hook directly into the openObserver and closeObserver Events but failed.


  2. If you want to use Angular signal withing RxJS chain you need to convert it into Observable using toObservable provided by @angular/core/rxjs-interop:

    Then you can use it within takeUntil()

    takeUntil(toObservable(this.WSStatus))
    

    Note, that you might need to provide Injector yourself because toObservable uses inject(Injector) by default which is I think available only in components constructor.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search