如何使用 SubscriberServiceApiClient.Pull() 取消与 C# 客户端库的同步拉取请求?

Posted

技术标签:

【中文标题】如何使用 SubscriberServiceApiClient.Pull() 取消与 C# 客户端库的同步拉取请求?【英文标题】:How to cancel a synchonous pull request with C# client library using SubscriberServiceApiClient.Pull()? 【发布时间】:2019-05-02 12:08:31 【问题描述】:

我想对订阅执行同步拉取操作,并希望等到至少一条消息可用。我使用此代码:

SubscriberServiceApiClient client = SubscriberServiceApiClient.Create();
SubscriptionName subscriptionName = new SubscriptionName(projectId, subscriptionId);
PullResponse pullResponse = client.Pull(subscriptionName, returnImmediately: false, maxMessages: 10);

根据api documentation,当returnImmediately设置为false时,客户端可以取消请求。从该文档中:

如果此字段设置为 true,即使在 Pull 响应中没有可返回的消息,系统也会立即响应。否则,系统可能会等待(一段时间)直到至少有一条消息可用,而不是不返回任何消息。如果客户端不想再等待响应,客户端可以取消请求。

但是,我不知道如何取消此拉取请求。

当订阅中没有可用消息时,此调用只会阻塞,直到 10 分钟后我收到 RpcException,这是默认的 RPC 到期:

Grpc.Core.RpcException: Status(StatusCode=DeadlineExceeded, Detail="Deadline Exceeded")

here 提出了类似的问题,但答案是针对旧 API 版本上的 Java 客户端。我使用 .NET 客户端的最新 GA 版本 (Google.Cloud.PubSub.V1)。

【问题讨论】:

API 文档是针对“原始”客户端编写的 - 可以取消 RPC。我不相信我们以同步的方式从 C# 库中公开任何这样做的方式。如果您可以改用异步方法,则可以提供一个取消令牌,然后取消。 【参考方案1】:

SubscriberServiceApiClient.Pull() 方法接受一个可选参数callSettings,例如,您可以这样使用:

SubscriberServiceApiClient client = SubscriberServiceApiClient.Create();
SubscriptionName subscriptionName = new SubscriptionName(projectId, subscriptionId);
PullResponse pullResponse = client.Pull(
  subscriptionName, returnImmediately: false, maxMessages: 10,
  CallSettings.FromCancellationToken(token));

// you could also specify the maximum time the Pull() method should block:
PullResponse pullResponse = client.Pull(
  subscriptionName, returnImmediately: false, maxMessages: 10,
  CallSettings.FromCallTiming(CallTiming.FromTimeout(TimeSpan.FromSeconds(30))));

【讨论】:

以上是关于如何使用 SubscriberServiceApiClient.Pull() 取消与 C# 客户端库的同步拉取请求?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用本机反应创建登录以及如何验证会话

如何在自动布局中使用约束标识符以及如何使用标识符更改约束? [迅速]

如何使用 AngularJS 的 ng-model 创建一个数组以及如何使用 jquery 提交?

如何使用laravel保存所有行数据每个行名或相等

如何使用 Math.Net 连接矩阵。如何使用 Math.Net 调用特定的行或列?

WSARecv 如何使用 lpOverlapped?如何手动发出事件信号?