protobuf概览
protobuf
protobuf是由谷歌推出的二进制序列化与反序列化库对象。也是著名GRPC的底层依赖,它独立于平台及语言的序列化与反序列化标准库。
相关网址
- protobuf IDL描述
- protobuf 开源库
- grpc-知乎
- grpc官方示例
安装protobuf可以使用vcpkg进行简易安装依赖,protoc.exe则会安装在installed\x64-windows\tools\protobuf目录下,protbuf是谷歌推出的grpc的基础序列化,包括QtGrpc也是依赖的此模块作为基础。
.proto是接口描述文件,它抽象在平台之外,提供了许多语言的支持这个支持是由谷歌推出。 所以你可以说protobuf是跨平台跨语言的一直序列化格式,至于支持到什么程序就要看谷歌的支持了。相对于json、xml之类的文本序列化格式,具有更高的效率,具有差不多程度的跨语言以及平台特性。
安装指令
vcpkg install protobuf protobuf:x64-windows // 安装protobuf
vcpkg install protobuf[zlib] protobuf[zlib]:x64-windows // 安装protobuf zlib压缩
vcpkg install grpc:x64-windows // 安装grpc
protoc指令
// protobuf
// proto IDL生成cpp代码文件 --cpp_out必须是已经存在的目录 proto dir则是存放.proto文件的目录 *.proto IDL接口文件
protoc --proto_path=[input: proto dir] --cpp_out=[output: cxx dir] [*.proto]
protoc --proto_path=./. --cpp_out=./ user.proto// grpc
// proto IDL生成cpp grpc代码文件 --grpc_out是grpc文件目录 --cpp_out cxx代码文件目录 --plugin 插件模式及插件软件 *.proto IDL接口文件
protoc --grpc_out=[output: grpc dir] --cpp_out=[output: cxx dir] --plugin=protoc-gen-grpc=[input: pligin] [*.proto]
.\protoc.exe --grpc_out=./ --cpp_out=./ --plugin=protoc-gen-grpc=grpc_cpp_plugin.exe .\serve.proto
user.proto 文件示例
syntax = "proto2";package jie;message Person {optional string name = 1;optional int32 id = 2;optional string email = 3;enum PhoneType {MOBILE = 0;HOME = 1;WORK = 2;}message PhoneNumber {optional string number = 1;optional PhoneType type = 2 [default = HOME];}repeated PhoneNumber phones = 4;
}message AddressBook {repeated Person people = 1;
}
vcpkg安装protobuf项目使用的配置示例
cmake_minimum_required(VERSION 3.5)set(CMAKE_TOOLCHAIN_FILE "D:/vcpkg/scripts/buildsystems/vcpkg.cmake" CACHE STRING "Vcpkg toolchain file")project(protobuf_item LANGUAGES CXX)set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)include(D:/vcpkg/scripts/buildsystems/vcpkg.cmake)find_package(protobuf CONFIG REQUIRED)# protbuf提供的根据.proto文件生成对应的头文件与cc文件
protobuf_generate_cpp(PROTO_SRCS PROTO_HDRS user.proto)
#protobuf_generate_cpp(PROTO_SRCS PROTO_HDRS EXPORT_MACRO DLL_EXPORT user.proto)
#protobuf_generate_cpp(PROTO_SRCS PROTO_HDRS DESCRIPTORS PROTO_DESCS user.proto)#message(==============================)
#message(${PROTO_SRCS})
#message(${PROTO_HDRS})
#message(==============================)add_executable(protobuf_item main.cpp ${PROTO_SRCS} ${PROTO_HDRS})target_include_directories(${PROJECT_NAME} PRIVATE ${CMAKE_BINARY_DIR})target_link_libraries(${PROJECT_NAME} PRIVATE protobuf::libprotoc protobuf::libprotobuf protobuf::libprotobuf-lite)
grpc
RPC,全称Remote Procedure Call,中文译为远程过程调用。通俗地讲,使用RPC进行通信,调用远程函数就像调用本地函数一样,RPC底层会做好数据的序列化与传输,从而能使我们更轻松地创建分布式应用和服务。
一般来讲,实现一个gRPC服务端和客户端,主要分为这几步:
- 安装 protobuf 依赖
- 编写 proto 文件(IDL)
- 编译 proto 文件(生成stub文件)
- 编写server端,实现我们的接口
- 编写client端,测试我们的接口
ps:大多数时候我们可以手动使用protoc + grpc_cpp_plugin来生成 .proto对应的代码来给程序使用,这样能简化grpc配置上带来的复杂操作。当然如果你想通过cmake配置文件生成对应的.proto 代码文件也无可厚非,如果你有此想法需要研究cmake中的add_custom_command()指令。
一个serve.proto IDL描述文件示例
// Copyright 2015 gRPC authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.syntax = "proto3";option java_multiple_files = true;
option java_package = "io.grpc.examples.helloworld";
option java_outer_classname = "HelloWorldProto";
option objc_class_prefix = "HLW";package jie;// The greeting service definition.
service Greeter {// Sends a greetingrpc SayHello (HelloRequest) returns (HelloReply) {}rpc SayHelloStreamReply (HelloRequest) returns (stream HelloReply) {}
}// The request message containing the user's name.
message HelloRequest {string name = 1;
}// The response message containing the greetings
message HelloReply {string message = 1;
}
grpc服务端与客户端cmake配置
cmake_minimum_required(VERSION 3.5)# 设置工具链
set(CMAKE_TOOLCHAIN_FILE "D:/vcpkg/scripts/buildsystems/vcpkg.cmake" CACHE STRING "Vcpkg toolchain file")project(grpc_item LANGUAGES CXX)set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)# 引入vcpkg.cmake子模块
include(D:/vcpkg/scripts/buildsystems/vcpkg.cmake)# 使用gRPC库
find_package(gRPC CONFIG REQUIRED)#protobuf_generate_cpp(PROTO_SRCS PROTO_HDRS user.proto)# 查找到执行的 proto命令行以及grpc_cpp_plugin 插件
find_program(_GRPC_CPP_PLUGIN_EXECUTABLE grpc_cpp_plugin)
find_program(_PROTOBUF_PROTOC protoc)# 设置文件路径绝对路径
get_filename_component(hw_proto "serve.proto" ABSOLUTE)
# 获取文件所在的目录
get_filename_component(hw_proto_path "${hw_proto}" PATH)# 设置输出的文件变量
set(hw_proto_srcs "${CMAKE_SOURCE_DIR}/serve.pb.cc")
set(hw_proto_hdrs "${CMAKE_SOURCE_DIR}/serve.pb.h")
set(hw_grpc_srcs "${CMAKE_SOURCE_DIR}/serve.grpc.pb.cc")
set(hw_grpc_hdrs "${CMAKE_SOURCE_DIR}/serve.grpc.pb.h")# 执行命令,OUTPUT参数为执行命令后最终输出的文件,需要完全匹配 DEPENDS依赖文件依然如此,这规则令人感到困惑。但你可以理解为COMMADN最终的输出文件为 OUTPUT参数,COMMAND输入文件文则是DEPENDS,但组织命令参数时仍需要这些参数。
add_custom_command(OUTPUT "${hw_grpc_srcs}" "${hw_grpc_hdrs}" "${hw_proto_srcs}" "${hw_proto_hdrs}"COMMAND ${_PROTOBUF_PROTOC}ARGS --grpc_out "${CMAKE_SOURCE_DIR}"--cpp_out "${CMAKE_SOURCE_DIR}"-I "${hw_proto_path}"--plugin=protoc-gen-grpc="${_GRPC_CPP_PLUGIN_EXECUTABLE}""${hw_proto}"DEPENDS "${hw_proto}")add_executable(grpc_item main.cpp${PROTO_SRCS} ${PROTO_HDRS}${hw_grpc_srcs} ${hw_grpc_hdrs}${hw_proto_srcs} ${hw_proto_hdrs}
)#target_include_directories(${PROJECT_NAME} PRIVATE ${CMAKE_BINARY_DIR})target_link_libraries(${PROJECT_NAME} PRIVATE gRPC::gpr gRPC::grpc gRPC::grpc++ gRPC::grpc++_alts)
grpc服务器代码
#include <iostream>
#include <grpcpp/ext/proto_server_reflection_plugin.h>
#include <grpcpp/grpcpp.h>
#include <grpcpp/server.h>
#include <grpcpp/health_check_service_interface.h>
#include "serve.grpc.pb.h"class JieRpc : public jie::Greeter::Service {
public:::grpc::Status SayHello(::grpc::ServerContext* context,const ::jie::HelloRequest* request,::jie::HelloReply* response) override {std::cout << request->name() << std::endl;response->set_message("hello Jie Rpc");return ::grpc::Status::OK;}::grpc::Status SayHelloStreamReply(::grpc::ServerContext* context,const ::jie::HelloRequest* request,::grpc::ServerWriter< ::jie::HelloReply>* writer) override {return ::grpc::Status::OK;}
};int main()
{JieRpc rpc;grpc::ServerBuilder builder;builder.AddListeningPort("localhost:9000", grpc::InsecureServerCredentials());builder.RegisterService(&rpc);std::unique_ptr<grpc::Server> server(builder.BuildAndStart());server->Wait();
}
grpc客户端代码
#include <iostream>
#include <grpcpp/grpcpp.h>
#include "serve.grpc.pb.h"int main()
{std::unique_ptr<jie::Greeter::Stub> stu(jie::Greeter::NewStub(grpc::CreateChannel("localhost:9000", grpc::InsecureChannelCredentials())));jie::HelloRequest request;jie::HelloReply reply;request.set_name("hello jie");grpc::ClientContext context;grpc::Status status = stu->SayHello(&context, request, &reply);if (status.ok())std::cout << reply.message() << std::endl;
}相关文章:
protobuf概览
protobuf protobuf是由谷歌推出的二进制序列化与反序列化库对象。也是著名GRPC的底层依赖,它独立于平台及语言的序列化与反序列化标准库。 相关网址 protobuf IDL描述protobuf 开源库grpc-知乎grpc官方示例 安装protobuf可以使用vcpkg进行简易安装依赖ÿ…...
<C++> SSE指令集
SSE指令集 include库 #include <mmintrin.h> //MMX #include <xmmintrin.h> //SSE(include mmintrin.h) #include <emmintrin.h> //SSE2(include xmmintrin.h) #include <pmmintrin.h> //SSE3(include emmintrin.h) #include <tmmintrin.h> /…...
cortex-A7核LED灯实验--STM32MP157
实验目的:实现LED1 / LED2 / LED3三盏灯工作 一,分析电路图 1,思路 分析电路图可知: 网络编号 引脚编号 LED1 PE10 LED2 > PF10 LED3 > PE8 2,工作原理: 写1:LED灯亮…...
WPF实战项目十三(API篇):备忘录功能api接口、优化待办事项api接口
1、新建MenoDto.cs /// <summary>/// 备忘录传输实体/// </summary>public class MenoDto : BaseDto{private string title;/// <summary>/// 标题/// </summary>public string Title{get { return title; }set { title value; }}private string con…...
clickhouse(十四、分布式DDL阻塞及同步阻塞问题)
文章目录 一、分布式ddl 阻塞、超时现象验证方法解决方案 二、副本同步阻塞现象验证解决方案 一、分布式ddl 阻塞、超时 现象 在clickhouse 集群的操作中,如果同时执行一些重量级变更语句,往往会引起阻塞。 一般是由于节点堆积过多耗时的ddl。然后抛出…...
怎么入门网络安全(黑客)?
目录: 一、自学网络安全学习的误区和陷阱 1.不要试图先成为一名程序员(以编程为基础的学习)再开始学习2.不要把深度学习作为入门第一课3.以黑客技能、兴趣为方向的自学误区:4.不要收集过多的资料二、学习网络安全的一些前期准备三…...
c++ boost::json
Boost社区12月11日发布了1.75版本,在之前,Boost使用Boost.PropertyTree解析JSON,XML,INI和INFO格式的文件。但是由于成文较早及需要兼容其他的数据格式,相比较于其他的…...
《Flink学习笔记》——第九章 多流转换
无论是基本的简单转换和聚合,还是基于窗口的计算,我们都是针对一条流上的数据进行处理的。而在实际应用中,可能需要将不同来源的数据连接合并在一起处理,也有可能需要将一条流拆分开,所以经常会有对多条流进行处理的场…...
openmmlab出现KeyError: ‘xxx is not in the model registry....‘
问题描述 在复现基于mmpose框架的算法时,运行程序出现KeyError: xxx is not in the model registry....的问题,报错原因是自定义的backbone等结构或者某些当前代码使用的方法没有注册到现有的包中, 导致在import的时候无法导入该方法。 解决方案 找到…...
错误代码0x80131500要怎么解决?快速修复方法
错误代码0x80131500通常与.NET Framework 相关的问题有关。它可能表示.NET Framework的安装损坏、版本冲突或系统文件缺失等。下面我们一起来探讨一下解决错误代码0x80131500有哪些。 以下是一些解决方法 安装最新的.NET Framework版本:访问Microsoft官方网站&…...
PMO(Project Management Office)
PMO 是项目管理办公室(Project Management Office)的缩写。它是组织内的一个部门或团队,负责支持和促进项目管理活动,以确保项目按时、按预算、按要求完成。 PMO 的职责和角色可以因组织的性质和需求而有所不同,但通常…...
STM32 CUBEMX CAN通信数据发送失败原因分析
CAN通信是一种数据通信协议,用于在不同设备之间进行通信。它是一种高效的、实时的、可靠的、多主机的、串行通信系统,通常用于汽车电子、工业自动化等领域。CAN通信协议是由德国BOSCH公司于1986年引入,并在欧洲和日本广泛使用。CAN通信具有独…...
长安链并行调度机制(2):DAG构建和从节点执行流程
长安链采用高效的并行调度方式执行交易,了解长安链交易调度、冲突检测和DAG构建流程有助于开发者更好地理解长安链并行调度的运行机制,帮助开发者编写高质量、低冲突的智能合约,更好地构建区块链应用。 上一篇内容我们说明了长安链交易调度、…...
leetcode做题笔记110. 平衡二叉树
给定一个二叉树,判断它是否是高度平衡的二叉树。 本题中,一棵高度平衡二叉树定义为: 一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1 。 思路一:递归 int height(struct TreeNode* root) {if (root NULL) {return…...
iOS开发Swift-字符串与字符
1.字符串的定义 let someString "some string value"2.多行字符串的定义(""") let quotation """ 有一个人前来买瓜。 "这瓜甜吗?"他问。 """前一个"""前和后一个""&…...
Linux Kernel:syscall之fork与exec
环境: Kernel Version:Linux-5.10 ARCH:ARM64 一:前言 上一节我们提到了进程的产生方式fork,exec与clone,本节将详细分析fork和exec族系统调用的具体实现。通常这些调用不是由应用程序直接发出的,而是通过一个中间层调用,即负责与内核通信的C标准库。从用户状态切换到…...
CentOS 修改MySQL密码
CentOS 修改MySQL密码 1.登录MySQL 2.执行如下命令 update user set passwordpassword(mivbAs7Awc) where userroot;报错如下: Unknown column ‘password’ in ‘field list’ 3.执行如下命令 update user set passwordpassword(mivbAs7Awc) where userroot碰到…...
Android通过setaffinity实现绑核
有时候为了降低App算力占用,会把关键的线程绑定到大核中,下面介绍一种绑核的方式 查看绑核 查看pid :/ # ps -A | grep test u0_a15 25178 405 15950272 176544 do_epoll_wait 0 S com.test.jnites查看线程号 top -H -p 25178 25224 u0_…...
stm32的位带操作
在51单片机中,我们可以使用P2^1来对单片机的某一位进行操作,到了stm32,我们通过位带操作,将寄存器的每一位映射到一个32位的地址。如下是我查资料摘录的一些图片。 映射方式 SRAM: AliasAddr 0x22000000 (A-0X20000000)*8*4n*4…...
Java 电子招标采购系统源码:营造全面规范安全的电子招投标环境,促进招投标市场健康可持续发展
营造全面规范安全的电子招投标环境,促进招投标市场健康可持续发展 传统采购模式面临的挑战 一、立项管理 1、招标立项申请 功能点:招标类项目立项申请入口,用户可以保存为草稿,提交。 2、非招标立项申请 功能点:非招标…...
stm32G473的flash模式是单bank还是双bank?
今天突然有人stm32G473的flash模式是单bank还是双bank?由于时间太久,我真忘记了。搜搜发现,还真有人和我一样。见下面的链接:https://shequ.stmicroelectronics.cn/forum.php?modviewthread&tid644563 根据STM32G4系列参考手…...
MySQL 隔离级别:脏读、幻读及不可重复读的原理与示例
一、MySQL 隔离级别 MySQL 提供了四种隔离级别,用于控制事务之间的并发访问以及数据的可见性,不同隔离级别对脏读、幻读、不可重复读这几种并发数据问题有着不同的处理方式,具体如下: 隔离级别脏读不可重复读幻读性能特点及锁机制读未提交(READ UNCOMMITTED)允许出现允许…...
遍历 Map 类型集合的方法汇总
1 方法一 先用方法 keySet() 获取集合中的所有键。再通过 gey(key) 方法用对应键获取值 import java.util.HashMap; import java.util.Set;public class Test {public static void main(String[] args) {HashMap hashMap new HashMap();hashMap.put("语文",99);has…...
Qwen3-Embedding-0.6B深度解析:多语言语义检索的轻量级利器
第一章 引言:语义表示的新时代挑战与Qwen3的破局之路 1.1 文本嵌入的核心价值与技术演进 在人工智能领域,文本嵌入技术如同连接自然语言与机器理解的“神经突触”——它将人类语言转化为计算机可计算的语义向量,支撑着搜索引擎、推荐系统、…...
Python爬虫(一):爬虫伪装
一、网站防爬机制概述 在当今互联网环境中,具有一定规模或盈利性质的网站几乎都实施了各种防爬措施。这些措施主要分为两大类: 身份验证机制:直接将未经授权的爬虫阻挡在外反爬技术体系:通过各种技术手段增加爬虫获取数据的难度…...
HTML前端开发:JavaScript 常用事件详解
作为前端开发的核心,JavaScript 事件是用户与网页交互的基础。以下是常见事件的详细说明和用法示例: 1. onclick - 点击事件 当元素被单击时触发(左键点击) button.onclick function() {alert("按钮被点击了!&…...
在鸿蒙HarmonyOS 5中使用DevEco Studio实现录音机应用
1. 项目配置与权限设置 1.1 配置module.json5 {"module": {"requestPermissions": [{"name": "ohos.permission.MICROPHONE","reason": "录音需要麦克风权限"},{"name": "ohos.permission.WRITE…...
MySQL用户和授权
开放MySQL白名单 可以通过iptables-save命令确认对应客户端ip是否可以访问MySQL服务: test: # iptables-save | grep 3306 -A mp_srv_whitelist -s 172.16.14.102/32 -p tcp -m tcp --dport 3306 -j ACCEPT -A mp_srv_whitelist -s 172.16.4.16/32 -p tcp -m tcp -…...
RNN避坑指南:从数学推导到LSTM/GRU工业级部署实战流程
本文较长,建议点赞收藏,以免遗失。更多AI大模型应用开发学习视频及资料,尽在聚客AI学院。 本文全面剖析RNN核心原理,深入讲解梯度消失/爆炸问题,并通过LSTM/GRU结构实现解决方案,提供时间序列预测和文本生成…...
高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数
高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数 在软件开发中,单例模式(Singleton Pattern)是一种常见的设计模式,确保一个类仅有一个实例,并提供一个全局访问点。在多线程环境下,实现单例模式时需要注意线程安全问题,以防止多个线程同时创建实例,导致…...
