将自定义传输插入gRPC

时间:2017-11-05 21:47:08

标签: c++ grpc

我们假设我们为gRPC开发了一个自定义低级传输。我们如何将它“插入”gRPC c ++ API,以便我们可以将它用于频道?

2 个答案:

答案 0 :(得分:3)

我正在处理即将出现在https://github.com/grpc/grpc/的文档,但这是预览:

gRPC transports插入核心API(C ++ API下一级)。您可以用C或C ++编写传输;目前所有的传输都名义上用C ++编写,虽然它们是惯用的C.现有的传输是:

其中,过程可能是最容易理解的,尽管可以说也是最不相似的真实"基于套接字的传输。

在gRPC核心实现中,基本结构是grpc_transport_stream_op_batch,它表示发送到传输的流操作的集合。批处理中的操作可以包括:

  • send_initial_metadata
    • 客户端:启动RPC
    • 服务器:提供响应标头
  • recv_initial_metadata
    • 客户:获取回复标题
    • 服务器:接受RPC
  • send_message(零或更多):发送数据缓冲区
  • recv_message(零或更多):接收数据缓冲区
  • send_trailing_metadata
    • 客户:半关闭表示不再有消息
    • 服务器:完全关闭提供RPC的最终状态
  • recv_trailing_metadata:获取RPC的最终状态
    • 服务器额外:在服务器还发送尾随元数据以向另一方提供最终状态之前,该操作系统实际上不应被视为完成
  • cancel_stream:尝试取消RPC
  • collect_stats:获取统计资料

这些操作中的一个或多个被分组为批处理。应用程序可以在一个批处理中启动所有呼叫操作,也可以将它们分成多个批处理。每个批次的结果通过完成队列异步返回。

在内部,我们使用回调来表示完成。表面层在启动新批次时创建回调,并将其与批次一起发送到过滤器堆栈。传输必须在批处理完成时调用此回调,然后表面层通过完成队列将事件返回给应用程序。每批最多可以有3个回调:

  • recv_initial_metadata_ready(当recv_initial_metadata操作完成时由传输调用)
  • recv_message_ready(当recv_message操作完成时由传输调用)
  • on_complete(整个批次完成后由传输调用)

传输的工作是对基本流操作的各种可能的交错进行排序和解释。例如,批次的样本时间轴将是:

  1. 客户端send_initial_metadata:使用路径(方法)和权限启动RPC
  2. 服务器receive_initial_metadata:接受RPC
  3. 客户端send_message:为RPC提供输入原型
  4. 服务器receive_message:从RPC获取输入原型
  5. 客户端send_trailing_metadata:这是半关闭,表示客户端不会再发送任何消息
  6. 服务器receive_trailing_metadata:服务器从客户端看到这一点,并知道它不会再收到任何消息。但是,如上所述,这还没有完成。
  7. 服务器send_initial_metadata,send_message,send_trailing_metadata:批处理可以包含多个操作,此批处理提供RPC响应标头,响应内容和状态。请注意,发送尾随元数据还将完成服务器的尾随元数据接收。
  8. 客户端recv_initial_metadata:批次一侧的操作数与批次另一侧的操作数无关。在这种情况下,客户端只是收集响应头。
  9. 客户端recv_message,recv_trailing_metadata:获取数据响应和状态
  10. 除了这些基本流操作之外,传输必须随时处理流的取消并将其效果传递给另一方。传输必须执行ping和统计等操作,这些操作用于形成流控制等传输级特性(例如,参见它们在HTTP / 2传输中的使用)。

答案 1 :(得分:0)

关于C ++ API:大多数现有的自定义传输是通过创建自己的凭据C ++类型并使用它们来启用新传输来完成的。