简体   繁体   English

使用RxJS和angular 2 HTTP服务重新连接服务器

[英]Server reconnection using RxJS and angular 2 HTTP service

What is the best way to handle a server reconnection using RxJS and Angular 2? 使用RxJS和Angular 2处理服务器重新连接的最佳方法是什么?

This is what I have so far: 这是我到目前为止的内容:

import { Injectable } from '@angular/core';
import { Http, Response } from '@angular/http';

import { Observable } from 'rxjs/Observable';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
import 'rxjs/add/operator/takeUntil';
import 'rxjs/add/observable/throw';

@Injectable()
export class ConnectionService {

  // Stores the current status of the connection, false = not connected
  serviceOnline: BehaviorSubject<boolean> = new BehaviorSubject(false)

  constructor(
    private http: Http
  ) {
    this.serviceOnline.asObservable().subscribe((online) => {
      console.log("Service online: " + JSON.stringify(online))
    })
    setTimeout( () => this.setServiceOffline(), 2000 );
  }

  setServiceOffline() {
    console.log("Setting service offline");
    this.serviceOnline.next(false);
    this.testConnection().delay(2000).repeat().takeUntil(this.serviceOnline).subscribe();
  }

  testConnection(): Observable<boolean> {
    console.log("Testing connection");
    return new Observable(observer => {
      this.http.get(`http://endpoint/ping`)
        .timeout(5000)
        .catch((error: any) => Observable.throw(error))
        .subscribe(() => {
          console.log("Connection successful");
          if(this.serviceOnline.getValue() == false)
            this.serviceOnline.next(true);
          observer.next(true);
          observer.complete();
        }, (error) => {
          console.log("Connection failed");
          if(this.serviceOnline.getValue() == true)
            this.serviceOnline.next(false);
          observer.next(false);
          observer.complete();
        });
    })
  }
}

Result in the console: 结果在控制台中:

Service online: false
Setting service offline
Service online: false
Testing connection
Connection failed

If I replace this line.. 如果我替换此行。

this.testConnection().delay(2000).repeat().takeUntil(this.serviceOnline).subscribe();

with

this.testConnection().delay(2000).repeat().take(5).subscribe();

I do get the repeats: 我确实得到了重复:

Service online: false
Setting service offline
Service online: false
Testing connection
Connection failed
Connection failed
Connection failed
Connection failed
Connection failed

From the documentation : 文档中

public takeUntil(notifier: Observable): Observable public takeUntil(通知者:可观察):可观察

Emits the values emitted by the source Observable until a notifier Observable emits a value. 发出由源Observable发出的值,直到通知者Observable发出一个值。

The serviceOnline BehaviorSubject is only updated if there is a change in the server status. 仅当服务器状态发生更改时,才会更新serviceOnline BehaviorSubject。 After this line... 在这行之后...

this.serviceOnline.next(false);

...serviceOnline only emits another value when the http service has returned a successful response and if the current online status is false (disconnected): ... serviceOnline仅在http服务返回成功响应并且当前在线状态为false(断开连接)时发出另一个值:

if(this.serviceOnline.getValue() == false)
   this.serviceOnline.next(true);

So takeUntil should work. 因此takeUntil应该起作用。 What am I misunderstanding/missing here? 我在这里误解/错过了什么?

I am new to RxJS - any other pointers on improving the implementation in this code would also be greatly appreciated... 我是RxJS的新手-改进此代码中实现的其他任何指针也将不胜感激...

Here is a Plnkr: http://plnkr.co/edit/WUKxH6nFxc8LMKcxDPql?p=info 这是一个Plnkr: http ://plnkr.co/edit/WUKxH6nFxc8LMKcxDPql?p=info

RxJS version 5.4. RxJS 5.4版。 Angular version 4. Angular版本4。


Returning serviceOnline as observable doesn't fix the issue: this.testConnection().delay(2000).repeat().takeUntil(this.serviceOnline.asObservable()).subscribe(); 将serviceOnline返回为observable不能解决问题:this.testConnection()。delay(2000).repeat()。takeUntil(this.serviceOnline.asObservable())。subscribe();

嗯,您是否尝试过这样做?:

this.testConnection().delay(2000).repeat().takeUntil(this.serviceOnline.asObservable()).subscribe();

I think the problem occurs because this.serviceOnline always emits the last value when subscribed to, as it is an instance of BehaviorSubject . 我认为出现问题是因为this.serviceOnline在订阅时始终发出最后一个值,因为它是BehaviorSubject的实例。 When you pass it to the takeUntil operator as a notifier observable, takeUntil subscribes to it and immediately receives a notification which leads to immediate completion of the resulting observable. 当您将其作为可观察的通知者传递给takeUntil运算符时, takeUntil订阅并立即收到一条通知,该通知会导致立即完成所生成的可观察对象。 Note that it doesn't matter whether the notifier observable emits true or false , takeUntil completes whenever it receives any value. 请注意,notifier observable发出truefalse takeUntiltakeUntil在接收到任何值时完成。

Try .takeUntil(this.serviceOnline.filter(online => online === true)) instead. 请尝试.takeUntil(this.serviceOnline.filter(online => online === true))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM