【发布时间】:2019-04-05 12:54:34
【问题描述】:
前言:
我以前没有使用过 gRPC。我只是初步了解这项技术,并试图了解我是否可以在我的项目中使用它。 我正在使用带有 net core 2.1 的 C#,如果它对某些事情很重要的话。
问题:
我有一台服务器和多个客户端,我需要从服务器向客户端发出 RPC 请求。它可以与 gRPC 一起使用吗?如果是这样,我该怎么做?
【问题讨论】:
前言:
我以前没有使用过 gRPC。我只是初步了解这项技术,并试图了解我是否可以在我的项目中使用它。 我正在使用带有 net core 2.1 的 C#,如果它对某些事情很重要的话。
问题:
我有一台服务器和多个客户端,我需要从服务器向客户端发出 RPC 请求。它可以与 gRPC 一起使用吗?如果是这样,我该怎么做?
【问题讨论】:
https://groups.google.com/forum/#!topic/grpc-io/wAF9T0nQcH0的回答
答案的作者:Josh Humphries(Josh,如果您会阅读此主题,请在此处发布您的答案,我会接受并删除我的副本)
您可以使用双向流,其中服务器在流上发送的每条消息都会有一条来自客户端的消息作为回复。实际的请求和响应类型都可以有一个 oneof:对于每个实际的 RPC 操作(及其请求类型),响应消息在 oneof 中都有一个选项;请求消息(由客户端发送)实际上会定义响应类型。您可以在服务器反射服务中看到类似的示例。然而,这是一种普通的客户端到服务器类型的 RPC。您只需交换请求和响应类型(让服务器通过首先发送“响应”消息并获得“请求”作为响应来发起请求)。
为了优雅地关闭,服务器只需停止使用流发送请求,等待所有未完成操作的回复,然后关闭流/终止 RPC。当客户端关闭时,它可能会停止接受来自服务器的消息(在收到每个消息后,立即发送一条类似于“正在关闭”的错误消息)。
如果您想支持乱序执行(例如,客户端回复的发送顺序可能与接收到服务器请求的顺序不同),那么请求和响应模式将需要有一个带有某种请求 ID 的信封,以便关联回复他们的原始请求。
顺便说一句:我一直在研究一些您可能会觉得有用的东西——一种用于隧道 gRPC 的通用机制。隧道是通过 gRPC 服务设置的,该服务提供与低级 gRPC 传输相同的功能。有一些有趣的用例,但服务器到客户端的用例是最有趣的 IMO。如果您好奇,可以查看正在进行的工作:https://github.com/jhump/grpctunnel。 (不幸的是,我不知道什么时候才能真正完成这个库,但它可能有一些你可以使用的有趣想法/代码。)
【讨论】:
使用 gRPC,服务器无法启动与客户端的联系。但是,客户端可以向服务器发送初始 rpc,然后等待它们的响应,直到服务器拥有所需的资源,如下所示:
using (var call = client.InitialContact(clientID))
{
var responseStream = call.ResponseStream;
while (await responseStream.MoveNext()){
//do something if there is a response
}
}
【讨论】:
服务器发起的请求不是 gRPC 的一流功能,但是,这种 PRC 拓扑结构始终可以通过流语义实现。
例如,流程是:
1) 所有客户端都与服务器建立长期流式 RPC
2) 服务器现在可以在这些流上向每个客户端发送消息,就好像每个消息都是一个单独的 RPC 一样
【讨论】: