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

Bal*_*nat 10 grpc grpc-java

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

rpc Subscribe (SubscribeRequest) returns (stream SubscribeResponse);
Run Code Online (Sandbox Code Playgroud)

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

我已经弄清楚客户端如何取消呼叫:

rpc Subscribe (SubscribeRequest) returns (stream SubscribeResponse);
Run Code Online (Sandbox Code Playgroud)

但是,服务器似乎没有注意到客户端已取消其调用。我正在用一个虚拟服务器实现来测试这个:

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

服务器会很高兴地继续将其消息发送到以太坊中。服务器如何识别调用已被客户端取消并因此停止发送响应?

Bal*_*nat 8

我自己找到了答案。您将StreamObserver传递的强制转换为 subscribe ServerCallStreamObserver,它公开了方法isCancelledsetOnCancelHandler

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

scso.setOnCancelHandler(handler);
// or
if (scso.isCancelled()) {
  // do whatever
}
Run Code Online (Sandbox Code Playgroud)

对我来说,这引出了一个问题,为什么subscribe没有通过 aServerCallStreamObserver开始。

  • @eric-anderson,我很抱歉,每当我看到“以前的用户”的争论时,我必须停止我正在做的一切,并大声疾呼。是的,2016 年,如果类型被重命名,可能有 10 个人在 Google 之外使用 gRPC 会注意到,但是到 2020 年,有 10000 个人使用 gRPC 会怎么样呢?为什么他们还会继续迷茫呢?然后是版本控制;在世界末日到来之前,API 不必向后兼容。 (2认同)