我可以跟踪RxJava订阅服务器中的事件消耗吗?

时间:2017-05-29 07:31:33

标签: rx-java rx-java2

我想跟踪订阅者何时开始使用事件以及何时完成。 是否存在适用于所有Observables / Subscribers的通用方法?

1 个答案:

答案 0 :(得分:6)

是1.x还是2.x?对于2.x,它可能会变得非常复杂,因为必须考虑所有内部协议,以免意外地对流量进行去优化。

否则,它可以像编写在真实Observer和运算符之间填充的Observer一样简单:

import io.reactivex.Observer;

RxJavaPlugins.setOnObservableSubscribe((observable, observer) -> {
    if (!observable.getClass().getName().toLowerCase().contains("map")) {
        return observer;
    }

    System.out.println("Started");

    class SignalTracker implements Observer<Object>, Disposable {
        Disposable upstream;
        @Override public void onSubscribe(Disposable d) {
            upstream = d;
            // write the code here that has to react to establishing the subscription
            observer.onSubscribe(this);
        }
        @Override public void onNext(Object o) {
            // handle onNext before or aftern notifying the downstream
            observer.onNext(o);
        }
        @Override public void onError(Throwable t) {
            // handle onError
            observer.onError(t);
        }
        @Override public void onComplete() {
            // handle onComplete
            System.out.println("Completed");
            observer.onComplete();
        }
        @Override public void dispose() {
            // handle dispose
            upstream.dispose();
        }
        @Override public boolean isDisposed() {
            return upstream.isDisposed();
        }
    }
    return new SignalTracker();
  });

  Observable<Integer> observable = Observable.range(1, 5)
      .subscribeOn(Schedulers.io())
      .observeOn(Schedulers.computation())
      .map(integer -> {
        try {
          TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
          e.printStackTrace();
        }
        return integer * 3;
      });

  observable.subscribe(System.out::println);

  Thread.sleep(6000L);

打印:

Started
3
6
9
12
15
Completed

编辑:RxJava 1版本需要更多lambdas但可行:

RxJavaHooks.setOnObservableStart((observable, onSubscribe) -> {
    if (!onSubscribe.getClass().getName().toLowerCase().contains("map")) {
        return onSubscribe;
    }

    System.out.println("Started");

    return (Observable.OnSubscribe<Object>)observer -> {
        class SignalTracker extends Subscriber<Object> {
            @Override public void onNext(Object o) {
                // handle onNext before or aftern notifying the downstream
                observer.onNext(o);
            }
            @Override public void onError(Throwable t) {
                // handle onError
                observer.onError(t);
            }
            @Override public void onCompleted() {
                // handle onComplete
                System.out.println("Completed");
                observer.onCompleted();
            }
            @Override public void setProducer(Producer p) {
                observer.setProducer(p);
            }
        }
        SignalTracker t = new SignalTracker()
        observer.add(t);
        onSubscribe.call(t);
    };
  });

  Observable<Integer> observable = Observable.range(1, 5)
      .subscribeOn(Schedulers.io())
      .observeOn(Schedulers.computation())
      .map(integer -> {
        try {
          TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
          e.printStackTrace();
        }
        return integer * 3;
      });

  observable.subscribe(System.out::println);

  Thread.sleep(6000L);