gRPC服务器如何通知客户端已取消服务器端流调用?

时间:2019-02-08 08:21:39

标签: grpc grpc-java

我想使用gRPC让客户端订阅服务器生成的事件。我有一个这样声明的RPC:

rpc Subscribe (SubscribeRequest) returns (stream SubscribeResponse);

其中返回的流是无限的。为了“退订”,客户端取消了RPC(顺便说一句,有没有更干净的方法?)。

我已经弄清楚了客户如何取消通话:

Context.CancellableContext cancellableContext =
         Context.current().withCancellation();
cancellableContext.run(() -> {
   stub.subscribe(request, callback);
});
// do other stuff / wait for reason to unsubscribe
cancellableContext.cancel(new InterruptedException());

但是,服务器似乎没有注意到客户端已取消其呼叫。我正在使用虚拟服务器实现对此进行测试:

@Override
public void subscribe(SubscribeRequest request,
                      StreamObserver<SubscribeResponse> responseObserver) {
  // in real code, this will happen in a separate thread.
  while (!Thread.interrupted()) {
    responseObserver.onNext(SubscribeResponse.getDefaultInstance());
  }
}

服务器将愉快地继续将其消息发送到以太。服务器如何识别客户端已取消呼叫并因此停止发送响应?

1 个答案:

答案 0 :(得分:0)

我自己找到了答案。您将传递的StreamObserver转换为预订ServerCallStreamObserver的方法,该方法公开了方法isCancelledsetOnCancelHandler

scso = ((ServerCallStreamObserver<SubscribeResponse>) responseObserver);

scso.setOnCancelHandler(handler);
// or
if (scso.isCancelled()) {
  // do whatever
}

这对我来说是一个问题,为什么subscribe最初没有通过ServerCallStreamObserver