angular - RxJS:WebSocket 重连处理

标签 angular websocket rxjs

我已经创建了一个服务来处理 WebSocket 连接以发送和接收消息,我正在处理一些可能发生断开连接的情况以及如何从中恢复,但我错过了浏览器的情况本身(可以这么说)脱机 它会在 navigator.onLine 再次发出 true 值时自​​动重试。

到目前为止,通过使用 retryWhen 运算符,我能够创建一个新 session 并重新启动它(如果服务器端出现问题),直到达到最大重试次数. 但是,通过使用 navigator.onLine(尽管它不可​​靠,我知道,但它适用于我们使用的浏览器)我可以在客户端离线时重新启动重新连接过程。

我有这个在线检查器可观察:

private onlineCheck: Observable<boolean>;

this.onlineCheck = merge(
      of(navigator.onLine),
      fromEvent(window, 'online').pipe(mapTo(true)),
      fromEvent(window, 'offline').pipe(mapTo(false)));

这就是我创建 WebSocket 的方式(并在需要时处理重新连接):

public connect(): void {
  // no more than one connection simultaneously
  if (!(this.socket == null)) {
    this.socket.complete();
  }

  this.socket = new WebSocketSubject(this.config);
  this.socket
    .pipe(
      retryWhen((errors) => {
        return errors.pipe(
          tap((error) => { console.log('Error: ', error); }),
          concatMap((e, i) =>
            iif(
              () => i < this.reconnectAttempts,
              of(e).pipe(delay(this.reconnectInterval)),
              throwError('Max amount of retries reached')
            )));
      }))
    .subscribe(
      (message: MessageEvent) => { this.onMessage(message); },
      (error: Event) => { this.onError(error); },
      () => { console.log('completed'); });
  }

如果客户端离线(并且达到最大连接重试次数),我如何将 onlineCheck 订阅与 retryWhen 运算符结合起来,以便重试它现在回来了吗? 如果这不是最好的方法,您能否推荐另一种方法?

这是一个完整的 StackBlitz 示例(检查控制台日志以获得更好的反馈):https://stackblitz.com/edit/angular-f4oa3y

最佳答案

在你的 iif 真实条件中,使用这个可观察的而不是 of(e).pipe(delay(this.reconnectInterval)):

timer(this.reconnectInterval) // wait for reconnect interval
  .pipe(
    concatMap(() => onlineCheck),
    first(Boolean) // now wait for online to be true
  )

在 reconnectInterval onlineCheck 为真后,它将发出一个将产生单个值的可观察对象

关于angular - RxJS:WebSocket 重连处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57925698/

相关文章:

node.js - Node原生mongodb驱动连接池问题

javascript - 如何处理来自封装函数的 Promise

angular - Angular 5 中的并行请求

Angular 表单不会发布到外部 URL

angular - 调用内部组件函数抛出未定义错误

node.js - 使用 Nodejs 和 Symfony 2 的 Websockets

javascript - 通过 Websocket 到 WebGL 与 Canvas 的图像传输,也许还可以与工作人员一起传输

Spring websocket没有主体

javascript - 如果 Observable 完成,我是否需要取消订阅 Observable?

javascript - 可观察异步的 rxJs 回调