Rx java 如何正确组合RxJava/Vert.x数据获取程序/GraphQL订阅

Rx java 如何正确组合RxJava/Vert.x数据获取程序/GraphQL订阅,rx-java,rx-java2,vert.x,Rx Java,Rx Java2,Vert.x,我有以下测试代码: FlowableOnSubscribe<SomeObj> fos; private void init() { fos = emitter -> { try { while(true) { SomeObj someObj = readFromDataInputStream(); emitter.onNext(someObj); System.out.pr

我有以下测试代码:

  FlowableOnSubscribe<SomeObj> fos;

  private void init() {
    fos = emitter -> {
      try {
        while(true) {
          SomeObj someObj = readFromDataInputStream();
          emitter.onNext(someObj);
          System.out.println("Emitted object");
        }
      }
      catch(Exception e) {
        emitter.onError(e);
      }
    };
  }

  public Single<String> doWork() {
    Flowable<String> myFlow = Flowable.defer(() -> 
      Flowable.create(fos, BackpressureStrategy.BUFFER)
        .cache()
        .subscribeOn(Schedulers.io(), false)
        .doOnSubscribe(x -> doSomethingToTriggerDataInputStream())
        .map(x -> convertMyCustomObjectToString(x))
      );
    );

    // lastOrError/singleOrError end up blocking :(
    return myFlow.firstOrError(); 
  }

  public VertxDataFetcher<CompletionStage<String>> vertxDataFetcherTest() {
    return new VertxDataFetcher<>((env, future) -> {
      try {
        future.complete(doWork().to(SingleInterop.get()));
      }
      catch(Exception e) {
        future.fail();
      }
    });
  }

  public DataFetcher<CompletionStage<String>> dataFetcherTest() {
    return env -> doWork().to(SingleInterop.get());
  }
可流动订阅fos;
私有void init(){
fos=发射器->{
试一试{
while(true){
SomeObj SomeObj=readFromDataInputStream();
发射器.onNext(someObj);
System.out.println(“发射对象”);
}
}
捕获(例外e){
发射体。onError(e);
}
};
}
公共单道具(){
可流动myFlow=可流动。延迟(()->
可流动。创建(fos,背压等级。缓冲区)
.cache()
.subscribeOn(Schedulers.io(),false)
.doOnSubscribe(x->doSomethingToTriggerDataInputStream())
.map(x->convertMyCustomObjectToString(x))
);
);
//lastOrError/singleOrError结束阻塞:(
返回myFlow.firstOrError();
}
公共VertxDataFetcher vertxDataFetcherTest(){
返回新的VertxDataFetcher((环境,未来)->{
试一试{
future.complete(doWork().to(SingleInterop.get());
}
捕获(例外e){
future.fail();
}
});
}
公共数据获取程序dataFetcherTest(){
返回env->doWork().to(SingleInterop.get());
}
如果我运行示例代码,它将在首次成功使用后挂起。换句话说,它将在初始网页加载时运行一次,但如果我在浏览器中刷新(Ctrl F5),它将挂起,并且不再完成调用

FWIW,经过一点调试,它看起来像 延迟/映射调用发生在RxCachedThreadScheduler1上,网页刷新后,它挂起在RxCachedThreadScheduler2的延迟调用中

如果我切换到为每个调用使用单独的输入流,它不会挂断

但是,这不适用于我的设计,因为它需要一个始终保持打开状态的共享连接。这是因为我希望GraphQL订阅能够捕获在数据输入流上发出的任何内容。如果我有多个/单独的套接字连接,GraphQL订阅输入流将丢失在non-订阅输入流(除非最好的选择是让每个其他输入流也向GraphQL订阅流发送,我不知道如何做…)


作为旁注,在这个场景中使用VertxDataFetcher与DataFetcher有关系吗?我目前正在使用DataFetcher来运行我的示例。如果我需要切换到VertxDataFetcher,我不确定如何正确转换类型以使该方法工作。

有很多相关的事情正在进行

您的发射器显然是阻塞的,因此您可以尝试的最重要的更改是在创建可流动的
时调用
.observeOn(RxHelper.blockingScheduler(vertx))
。了解有关如何使用适当的调度程序的更多信息


不过,这可能无法解决您的问题。您可能正在使用
readFromDataInputStream()
以阻塞、传统的Java IO方式读取数据,这可能是线程安全的,但几乎可以肯定它不支持并发读卡器。只要
readFromDataInputStream()
最终从同一IO读取。请参见

您好,谢谢您的输入,但我不确定这是否是我要寻找的。示例是发射器的一个实例,上面有多个观察者。我也尝试了RxHelper,但它不起作用(正如您也提到的)