C++下的gRPC与protobuf使用和介绍

news/2024/11/29 17:12:49/文章来源:https://www.cnblogs.com/yubo-guan/p/18577148

目录
  • gRPC允许定义四类服务方法
  • 流是会结束的
  • stream(流式传输)编写流程
  • 客户端使用 ClientReader
  • 客户端使用 ClientWriter
  • 客户端使用 ClientReaderWriter
  • 服务器端


gRPC允许定义四类服务方法

  1. 一元RPC:客户端发送一次请求,等待服务端响应结构,会话结束,就像一次普通的函数调用这样简单

    一元RPC
  2. 服务端流式RPC:客户端发起一起请求,服务端会返回一个流,客户端会从流中读取一系列消息,直到没有结果为止

    服务端流式RPC
  3. 客户端流式RPC:客户端提供一个数据流并写入消息发给服务端,一旦客户端发送完毕,就等待服务器读取这些消息并返回应答

    客户端流式RPC
  4. 双向流式RPC:客户端和服务端都提供一个数据流,都可以通过各自的流进行读写数据,这两个流是相互独立的,客户端和服务端都可以按其希望的任意顺序独写

    双向流式RPC

原文链接:https://blog.csdn.net/jianfeng123123/article/details/128110603


流是会结束的

并不似长连接,建立上之后就一直保持,有消息的时候发送。(是否有通过建立一个流 RPC 建立推送机制?)

Client 发送流,是通过 Writer->WritesDone() 函数结束流

Server 发送流,是通过结束 RPC 函数并返回状态码的方式来结束流

流接受者,都是通过 Reader->Read() 返回的 bool 型状态,来判断流是否结束

Server 并没有像 Client 一样调用 WriteDone(),而是在消息之后,将 status code、可选的 status message、可选的 trailing metadata 追加进行发送,这就意味着流结束了。


xxx.pb.hxxx.pb.cc: 生成我们编写的proto message数据结构类型的相关的方法,这两个文件是对proto文件中各消息结构的方法的创建和实现,清除,设置,获取等

xxx.grpc.pb.ccxxx.grpc.pb.h:生成proto文件中rpc函数客户端和服务器的相关方法,用于grpc服务器,客户端通讯相关的方法


stream(流式传输)编写流程

grpc的流式传输的有三种类: grpc::ClientReader; grpc::ClientWriter; grpc::ClientReaderWriter;

grpc::ClientReaderWriter类是输入输出都是流的函数类,例如代码中的Stream函数。

他们三个类基本方法都一样

  • ClientReaderWriter类中包含Read Write两个方法,可读可写
  • 而ClientReader类中包含Read方法,只可读
  • ClientWriter类中包含Write方法,只可写。

WritesDone方法(流数据写结束标识):ClientReaderWriter,ClientWriter都包含该方法。

Finish方法(读流数据结束标识):ClientReaderWriter,ClientReader都包含该方法。

三种类中的方法用法一样,grpc::ClientReader; grpc::ClientWriter不再做单独说明,用法和grpc::ClientReaderWriter一样。

使用哪个类就加上对应的命名空间的使用声明

  • 服务器:

    • using grpc::ServerReader;
    • using grpc::ServerWriter;
    • using grpc::ServerReaderWriter;
    • 服务器没有客户端的WritesDone()和 Finish()方法,用法参考代码,Read() Write()方法的使用和客户端是一样的。
  • 客户端:

    • using grpc::ClientReader;
    • using grpc::ClientWriter;
    • using grpc::ClientReaderWriter;

在gRPC中,流式传输(Streaming)是一种允许在单个RPC调用中发送多个消息序列的功能。这对于需要处理大量数据或需要实时交互的应用非常有用。以下是一个简化的流程,说明如何在gRPC中使用ClientReader, ClientWriter, 和 ClientReaderWriter 类进行流式传输的编写。


客户端使用 ClientReader

  1. 创建Stub:首先,你需要有一个gRPC服务的stub实例。

  2. 调用流式方法:通过stub调用服务定义中声明的流式方法,这将返回一个ClientReader对象。

  3. 读取数据:在循环中调用ClientReaderRead方法,该方法将尝试从服务器读取下一个消息。如果返回true,则消息已填充到传入的参数中;如果返回false,则表示没有更多消息可读(可能是因为流已关闭或发生错误)。

  4. 处理读取到的数据:在循环内部,处理从服务器接收到的每个消息。

  5. 完成读取:一旦Read方法返回false,通常意味着流已结束。此时,可以调用Finish方法来获取RPC调用的最终状态(成功或失败)。


客户端使用 ClientWriter

  1. 创建Stub:同样,首先需要gRPC服务的stub实例。

  2. 调用流式方法:通过stub调用服务定义中声明的流式方法,这将返回一个ClientWriter对象。

  3. 写入数据:在循环中调用ClientWriterWrite方法,将消息发送到服务器。继续发送消息直到所有数据都已发送。

  4. 标记写入完成:使用WritesDone方法标记所有消息都已发送完毕。这允许服务器知道不会再有更多的消息被发送,并开始处理已接收的消息。

  5. 完成写入:调用Finish方法等待服务器处理完所有消息并返回RPC调用的最终状态。


客户端使用 ClientReaderWriter

  1. 创建Stub:与前两者相同,首先需要gRPC服务的stub实例。

  2. 调用流式方法:通过stub调用服务定义中声明的双向流式方法,这将返回一个ClientReaderWriter对象。

  3. 读写数据:在需要时,可以在循环中交替调用Write方法和Read方法。发送消息到服务器并读取来自服务器的响应。

  4. 标记写入完成:当所有消息都已发送时,使用WritesDone方法标记写入完成。

  5. 完成读写:继续读取服务器的响应直到Read方法返回false,然后调用Finish方法等待RPC调用的最终状态。


服务器端

服务器端处理流式RPC的方式与客户端略有不同,但基本概念相同。服务器端使用ServerReader, ServerWriter, 或 ServerReaderWriter 来接收或发送消息。服务器端的实现需要处理这些流对象提供的读写操作,并在适当的时候返回RPC调用的结果。

请注意,实际实现细节(如错误处理、流控制等)可能会根据具体的应用场景和需求而有所不同。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/843518.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

uniapp 微信小程序 子组件行内样式通过父组件参数获取

uniapp中正常按vue写法没问题,但是编译成微信小程序时,style中会变成[object object],如下图 子组件可以通过计算属性处理一下传进来的style对象,代码如下<template><div><div>我是自定义组件</div><div :style="generateStyle">00{{t…

HuggingFace入门与实践

现在全民AI大模型,虽然我不是算法工程师,但是作为IT从业者,多少应该了解一下。然而,论文太多,原理太难,那咱们就从实践开始,先实践看效果,再学习研究原理。 1. 存在价值及原因简而言之:HuggingFace是菜鸟的福音,大佬的舞台,学术与工程的桥梁!平台链接:https://hug…

Filter内存马

概述 最近感冒了,不想BB太多,直接开始调试吧,先写个Filter来调试 Filter代码 新建一个FilterShell类,代码如下: 一个类如果想要成为Filter则需要继承Filter,然后重写init、doFilter、destory这三个方法,分别表示了init::Filter在初始化时被调用 doFilter:在Filter被命…

探索 TypeScript 编程的利器:ts-morph 入门与实践

我们是袋鼠云数栈 UED 团队,致力于打造优秀的一站式数据中台产品。我们始终保持工匠精神,探索前端道路,为社区积累并传播经验价值。本文作者:贝儿背景 在开发 web IDE 中生成代码大纲的功能时, 发现自己对 TypeScript 的了解知之甚少,以至于针对该功能的实现没有明确的思…

RK3562J正式支持NPU,性价比再提升!

RK3562J是瑞芯微最新推出的一款超高性价比工业处理器,四核Cortex-A53@1.8GHz + Cortex-M0@200MHz异构多核架构,并支持十路UART、两路CAN、两路网口、三种显示、双路Camera等,外设接口资源十分丰富,是RK3568J处理器降成本、降功耗的首选平台,在工商业储能EMS、通讯管理机、…

Movie相关

IDA-VLM: Towards Movie Understanding via ID-Aware Large Vision-Language Model 故事:现在的LVLM只能处理单场景,跨场景中关联实体的能力不行。比如电影中同一个角色在不同场景中出现,现有的LVLM不能把相同角色合并。所以本文提出了一个benchmark衡量跨场景角色对齐能力,…

PHY6236超低成本低功耗蓝牙芯片智能灯控家居

超低成本SOC蓝牙芯片PHY6236PHY6236 是一款用于低功耗蓝牙和专有 2.4G 应用的片上系统 (SoC)。它具有高性能低功耗 32 位 RISC-V MCU,具有 8KB 保留 SRAM、80KB ROM、8KB OTP 和超低功耗、高性能、多模式无线电。此外,PHY6236 还可以支持具有安全性和应用的 BLE。串行外设 IO…

20222411 2024-2025-1 《网络与系统攻防技术》实验五实验报告

1.实验内容 1.1 实践内容 (1)从www.besti.edu.cn、baidu.com、sina.com.cn中选择一个DNS域名进行查询,获取如下信息:DNS注册人及联系方式、该域名对应IP地址、IP地址注册人及联系方式、IP地址所在国家、城市和具体地理位置 PS:使用whois、dig、nslookup、traceroute、以及…

如何通过精准管理,推动产品按时交付

作为产品经理,项目管理是一项必须具备的核心能力。无论是从产品规划、开发到最终交付,项目管理贯穿了整个产品生命周期,涉及团队协调、进度控制、资源分配、质量保障等多个方面。有效的项目管理不仅能帮助团队按时交付高质量的产品,还能提升效率、降低成本并确保客户满意。…

js和CSS3媒体查询制作简单的响应式导航菜单

这是一款使用纯js和css3媒体查询制作的简单的响应式导航菜单效果。该导航菜单类似bootstrap导航菜单,它通过media query制作760像素断点,当视口小于760像素时,菜单会收缩为隐藏的汉堡包菜单。在线演示 下载使用方法HTML结构 该导航菜单使用<nav>元素最为包裹容器,di…

hhdb数据库介绍(10-4)

实例管理 该功能用来查看和管理所有计算节点集群中存储节点所在实例的主从关系。实例信息可以通过主机名、端口号、和存储节点版本号进行筛选。 实例管理信息 功能入口: 登录管理用户界面->实例管理实例管理信息以一个存储节点为单位显示一条记录,可对具体的存储节点进行“…

PE文件结构解析 Part3 NT Headers

文章来源:https://0xrick.github.io/win-internals/pe4/ 目录简介NT Headers(IMAGE_NT_HEADERS)签名 SignatureFile Header(IMAGE_FILE_HEADER)Optional Header (IMAGE_OPTIONAL_HEADER)总结 简介 在前面的文章中,我们看过了DOS Header的结构以及逆向了DOS stub。 这篇文章我…