使用RxJava进行服务器轮询 - 在确定服务器响应后重复

时间:2016-10-18 03:17:35

标签: rx-java reactive-programming polling

目前我正在尝试使用RxJava实现服务器轮询,我已经做了一些关于如何在接收服务器响应后重复整个链的研究,我已经尝试过使用repeat(),它的工作原理但不起作用那么完美,原因是因为它使api调用了这么多次,服务器在发送到客户端之前需要额外的时间来处理数据,但是我们不知道确切的时间,因此我们不能使用repeatWhen()来给出特定的时间。我唯一可以使用的是在api响应之后等待。

任何建议都将不胜感激!

以下是代码段:

retrofitService.requestPolling()
              .repeat()   // do not wait to call server so many times
              .takeUntil(new Func1<PollResponse, Boolean>() {
                      @Override
                      public Boolean call(PollResponse pollResponse) {
                            return pollResponse.mComplete;
                       }
               })
             .doOnNext(new Action1<FlightSearchPollResponse>() {
                @Override
                public void call(pollResponse pollResponse) {
                      // update UI here
                }
            })
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(new Observer<PollResponse>() {
                @Override
                public void onCompleted() {

                    }
                }

                @Override
                public void onError(Throwable e) {

                }

                @Override
                public void onNext(PollResponse pollResponse) {

            } );
编辑:我是RxJava的新手,只是得到了这个名为BackPressure的主题,并且有很多文章解释了如何处理它,因为我不想缓存这个响应,似乎主题会是一个不错的选择,它允许你控制何时拉。

http://akarnokd.blogspot.com/2015/06/subjects-part-1.html

感谢@Gary LO

1 个答案:

答案 0 :(得分:1)

应该有很多方法。我想分享其中一个。

  1. 创建单独的信号流PublishSubject pollingSignal
  2. 将信号转换为api调用
  3. 发布信号再次进行。

    final PublishSubject<Boolean> pollingSignal = PublishSubject.create();
    
    final Observable<PollResponse> apiResponse = retrofitService.requestPolling();
    
    pollingSignal
      .flatMap(x -> apiResponse)
      .subscribe(new Observer<PollResponse>() {
        @Override
        public void onCompleted() {}
    
        @Override
        public void onError(Throwable throwable) {}
    
        @Override
        public void onNext(PollResponse integer) {
          // start the next polling 
          pollingSignal.onNext(true);
      }
    });
    
    // start the first polling 
    pollingSignal.onNext(true);
    
  4. 玩得开心!

    备注 使用PublishSubject<Boolean>代替PublishSubject<Void>是因为我觉得使用pollingSignal.onNext(null)感觉不舒服。

    但是在Kotlin,我可以PublishSubject<Unit>使用pollingSignal.onNext(Unit)