热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

gRPC的使用(cpp)

gRPC是google开源的一套实现rpc调用的框架,支持多种语言,并且比较易用,其数据传输是通过google自家的protobuf来序列

gRPC是google开源的一套实现rpc调用的框架,支持多种语言,并且比较易用,其数据传输是通过google自家的protobuf来序列化的,下面我们通过改写gRPC的example来实现获取远程host内存的功能。


例子中的文件目录结构如下


./examples/cpp/sysproc
./examples/cpp/sysproc/sysproc_server.cc
./examples/cpp/sysproc/Makefile
./examples/protos/sysproc.proto

1.先定义protobuf文件

文件描述了接口的参数结构和接口结构
sysproc.proto

syntax = "proto3";service SysProcManager {rpc getSysProc (NullMessage) returns (SysProc) {}
}message NullMessage {}message SysProc {int32 memfree = 1;
}
;

由于这里的接口必须需要参数,所以我们增加了一个Null类型的消息
我们定义了一个SysProc消息结构用于getSysProc rpc方法的返回值,service的名字叫SysProcManager


服务器端代码

sysproc_service.cc

#include "sysproc.grpc.pb.h"
#include
#include
#include
#include
extern "C" {
#include
}using grpc::Server;
using grpc::ServerBuilder;
using grpc::ServerContext;
using grpc::Status;// Logic and data behind the server's behavior.
class SysProcServiceImpl final : public SysProcManager::Service {Status getSysProc(ServerContext* context, const NullMessage* request,SysProc * reply) override {int memFree = 0;struct sysinfo info;sysinfo(&info);memFree = (int)(info.freeram);reply->set_memfree(memFree);return Status::OK;}
};void RunServer() {std::string server_address("0.0.0.0:50051");SysProcServiceImpl service;ServerBuilder builder;// Listen on the given address without any authentication mechanism.builder.AddListeningPort(server_address, grpc::InsecureServerCredentials());// Register "service" as the instance through which we&#39;ll communicate with// clients. In this case it corresponds to an *synchronous* service.builder.RegisterService(&service);// Finally assemble the server.std::unique_ptr server(builder.BuildAndStart());std::cout <<"Server listening on " <std::endl;// Wait for the server to shutdown. Note that some other thread must be// responsible for shutting down the server for this call to ever return.server->Wait();
}int main(int argc, char** argv) {RunServer();return 0;
}

SysProcServiceImpl先定义了一个Service类继承自我们刚刚定义的protobuf文件编译产生的grpc的文件SysProcManager::Service&#xff0c;并实现getSysProc&#xff0c;在后面的Makefile文件中会看到编译的过程
通过ServiceBuilder创建一个builder并监听服务器端口&#xff0c;然后注册我们刚刚写的Service类&#xff0c;这时候就wait处理客户端请求就好了

sysproc_client.cc

#include
#include
#include #include #include "sysproc.grpc.pb.h"using grpc::Channel;
using grpc::ClientContext;
using grpc::Status;class SysProcClient {public://创建客户端类&#xff0c;该类通过一个SysProcManager&#xff08;protobuf定义的Service&#xff09;的stub来和服务器端进行通信SysProcClient(std::shared_ptr channel): stub_(SysProcManager::NewStub(channel)) {}// Assembles the client&#39;s payload, sends it and presents the response back// from the server.int getSysProc() {// Data we are sending to the server.NullMessage request;// Container for the data we expect from the server.SysProc reply;// Context for the client. It could be used to convey extra information to// the server and/or tweak certain RPC behaviors.ClientContext context;// The actual RPC.//stub调用生成的接口调用serviceStatus status &#61; stub_->getSysProc(&context, request, &reply);// Act upon its status.if (status.ok()) {return reply.memfree();} else {std::cout <": " <std::endl;return -1;}}private:std::unique_ptr stub_;
};int main(int argc, char** argv) {// Instantiate the client. It requires a channel, out of which the actual RPCs// are created. This channel models a connection to an endpoint (in this case,// localhost at port 50051). We indicate that the channel isn&#39;t authenticated// (use of InsecureChannelCredentials()).//创建一个chanel用于定义一个和服务器端的网络连接&#xff0c;传给client的stubSysProcClient sysproc_client(grpc::CreateChannel("localhost:50051", grpc::InsecureChannelCredentials()));int reply &#61; sysproc_client.getSysProc();std::cout <<"Client received: " <std::endl;return 0;
}

Makefile:

HOST_SYSTEM &#61; $(shell uname | cut -f 1 -d_)
SYSTEM ?&#61; $(HOST_SYSTEM)
CXX &#61; g&#43;&#43;
CPPFLAGS &#43;&#61; &#96;pkg-config --cflags protobuf grpc&#96;
CXXFLAGS &#43;&#61; -std&#61;c&#43;&#43;11
ifeq ($(SYSTEM),Darwin)
LDFLAGS &#43;&#61; -L/usr/local/lib &#96;pkg-config --libs protobuf grpc&#43;&#43; grpc&#96;\-lgrpc&#43;&#43;_reflection\-ldl
else
LDFLAGS &#43;&#61; -L/usr/local/lib &#96;pkg-config --libs protobuf grpc&#43;&#43; grpc&#96;\-Wl,--no-as-needed -lgrpc&#43;&#43;_reflection -Wl,--as-needed\-ldl
endif
PROTOC &#61; protoc
GRPC_CPP_PLUGIN &#61; grpc_cpp_plugin
GRPC_CPP_PLUGIN_PATH ?&#61; &#96;which $(GRPC_CPP_PLUGIN)&#96;PROTOS_PATH &#61; ../../protosvpath %.proto $(PROTOS_PATH)all: system-check sysproc_client sysproc_serversysproc_client: sysproc.pb.o sysproc.grpc.pb.o sysproc_client.o$(CXX) $^ $(LDFLAGS) -o $&#64;sysproc_server: sysproc.pb.o sysproc.grpc.pb.o sysproc_server.o$(CXX) $^ $(LDFLAGS) -o $&#64;.PRECIOUS: %.grpc.pb.cc
%.grpc.pb.cc: %.proto$(PROTOC) -I $(PROTOS_PATH) --grpc_out&#61;. --plugin&#61;protoc-gen-grpc&#61;$(GRPC_CPP_PLUGIN_PATH) $<.PRECIOUS: %.pb.cc
%.pb.cc: %.proto$(PROTOC) -I $(PROTOS_PATH) --cpp_out&#61;. $<clean:rm -f *.o *.pb.cc *.pb.h sysproc_client sysproc_server# The following is to test your system and ensure a smoother experience.
# They are by no means necessary to actually compile a grpc-enabled software.PROTOC_CMD &#61; which $(PROTOC)
PROTOC_CHECK_CMD &#61; $(PROTOC) --version | grep -q libprotoc.3
PLUGIN_CHECK_CMD &#61; which $(GRPC_CPP_PLUGIN)
HAS_PROTOC &#61; $(shell $(PROTOC_CMD) > /dev/null && echo true || echo false)
ifeq ($(HAS_PROTOC),true)
HAS_VALID_PROTOC &#61; $(shell $(PROTOC_CHECK_CMD) 2> /dev/null && echo true || echo false)
endif
HAS_PLUGIN &#61; $(shell $(PLUGIN_CHECK_CMD) > /dev/null && echo true || echo false)SYSTEM_OK &#61; false
ifeq ($(HAS_VALID_PROTOC),true)
ifeq ($(HAS_PLUGIN),true)
SYSTEM_OK &#61; true
endif
endifsystem-check:
ifneq ($(HAS_VALID_PROTOC),true)&#64;echo " DEPENDENCY ERROR"&#64;echo&#64;echo "You don&#39;t have protoc 3.0.0 installed in your path."&#64;echo "Please install Google protocol buffers 3.0.0 and its compiler."&#64;echo "You can find it here:"&#64;echo&#64;echo " https://github.com/google/protobuf/releases/tag/v3.0.0"&#64;echo&#64;echo "Here is what I get when trying to evaluate your version of protoc:"&#64;echo-$(PROTOC) --version&#64;echo&#64;echo
endif
ifneq ($(HAS_PLUGIN),true)&#64;echo " DEPENDENCY ERROR"&#64;echo&#64;echo "You don&#39;t have the grpc c&#43;&#43; protobuf plugin installed in your path."&#64;echo "Please install grpc. You can find it here:"&#64;echo&#64;echo " https://github.com/grpc/grpc"&#64;echo&#64;echo "Here is what I get when trying to detect if you have the plugin:"&#64;echo-which $(GRPC_CPP_PLUGIN)&#64;echo&#64;echo
endif
ifneq ($(SYSTEM_OK),true)&#64;false
endif

运行

先运行服务器sysproc_server&#xff0c;再运行sysproc_client就能看到结果的


推荐阅读
  • 本文讨论了如何使用Web.Config进行自定义配置节的配置转换。作者提到,他将msbuild设置为详细模式,但转换却忽略了带有替换转换的自定义部分的存在。 ... [详细]
  • 基于Socket的多个客户端之间的聊天功能实现方法
    本文介绍了基于Socket的多个客户端之间实现聊天功能的方法,包括服务器端的实现和客户端的实现。服务器端通过每个用户的输出流向特定用户发送消息,而客户端通过输入流接收消息。同时,还介绍了相关的实体类和Socket的基本概念。 ... [详细]
  • 搭建Windows Server 2012 R2 IIS8.5+PHP(FastCGI)+MySQL环境的详细步骤
    本文详细介绍了搭建Windows Server 2012 R2 IIS8.5+PHP(FastCGI)+MySQL环境的步骤,包括环境说明、相关软件下载的地址以及所需的插件下载地址。 ... [详细]
  • Centos7.6安装Gitlab教程及注意事项
    本文介绍了在Centos7.6系统下安装Gitlab的详细教程,并提供了一些注意事项。教程包括查看系统版本、安装必要的软件包、配置防火墙等步骤。同时,还强调了使用阿里云服务器时的特殊配置需求,以及建议至少4GB的可用RAM来运行GitLab。 ... [详细]
  • 如何使用Java获取服务器硬件信息和磁盘负载率
    本文介绍了使用Java编程语言获取服务器硬件信息和磁盘负载率的方法。首先在远程服务器上搭建一个支持服务端语言的HTTP服务,并获取服务器的磁盘信息,并将结果输出。然后在本地使用JS编写一个AJAX脚本,远程请求服务端的程序,得到结果并展示给用户。其中还介绍了如何提取硬盘序列号的方法。 ... [详细]
  • 本文介绍了Hyperledger Fabric外部链码构建与运行的相关知识,包括在Hyperledger Fabric 2.0版本之前链码构建和运行的困难性,外部构建模式的实现原理以及外部构建和运行API的使用方法。通过本文的介绍,读者可以了解到如何利用外部构建和运行的方式来实现链码的构建和运行,并且不再受限于特定的语言和部署环境。 ... [详细]
  • http:my.oschina.netleejun2005blog136820刚看到群里又有同学在说HTTP协议下的Get请求参数长度是有大小限制的,最大不能超过XX ... [详细]
  • 本文介绍了RPC框架Thrift的安装环境变量配置与第一个实例,讲解了RPC的概念以及如何解决跨语言、c++客户端、web服务端、远程调用等需求。Thrift开发方便上手快,性能和稳定性也不错,适合初学者学习和使用。 ... [详细]
  • 计算机存储系统的层次结构及其优势
    本文介绍了计算机存储系统的层次结构,包括高速缓存、主存储器和辅助存储器三个层次。通过分层存储数据可以提高程序的执行效率。计算机存储系统的层次结构将各种不同存储容量、存取速度和价格的存储器有机组合成整体,形成可寻址存储空间比主存储器空间大得多的存储整体。由于辅助存储器容量大、价格低,使得整体存储系统的平均价格降低。同时,高速缓存的存取速度可以和CPU的工作速度相匹配,进一步提高程序执行效率。 ... [详细]
  • 本文介绍了Web学习历程记录中关于Tomcat的基本概念和配置。首先解释了Web静态Web资源和动态Web资源的概念,以及C/S架构和B/S架构的区别。然后介绍了常见的Web服务器,包括Weblogic、WebSphere和Tomcat。接着详细讲解了Tomcat的虚拟主机、web应用和虚拟路径映射的概念和配置过程。最后简要介绍了http协议的作用。本文内容详实,适合初学者了解Tomcat的基础知识。 ... [详细]
  • 本文介绍了在使用Python中的aiohttp模块模拟服务器时出现的连接失败问题,并提供了相应的解决方法。文章中详细说明了出错的代码以及相关的软件版本和环境信息,同时也提到了相关的警告信息和函数的替代方案。通过阅读本文,读者可以了解到如何解决Python连接服务器失败的问题,并对aiohttp模块有更深入的了解。 ... [详细]
  • 本文介绍了如何使用C#制作Java+Mysql+Tomcat环境安装程序,实现一键式安装。通过将JDK、Mysql、Tomcat三者制作成一个安装包,解决了客户在安装软件时的复杂配置和繁琐问题,便于管理软件版本和系统集成。具体步骤包括配置JDK环境变量和安装Mysql服务,其中使用了MySQL Server 5.5社区版和my.ini文件。安装方法为通过命令行将目录转到mysql的bin目录下,执行mysqld --install MySQL5命令。 ... [详细]
  • Java在运行已编译完成的类时,是通过java虚拟机来装载和执行的,java虚拟机通过操作系统命令JAVA_HOMEbinjava–option来启 ... [详细]
  • Android系统源码分析Zygote和SystemServer启动过程详解
    本文详细解析了Android系统源码中Zygote和SystemServer的启动过程。首先介绍了系统framework层启动的内容,帮助理解四大组件的启动和管理过程。接着介绍了AMS、PMS等系统服务的作用和调用方式。然后详细分析了Zygote的启动过程,解释了Zygote在Android启动过程中的决定作用。最后通过时序图展示了整个过程。 ... [详细]
  • Hadoop 源码学习笔记(4)Hdfs 数据读写流程分析
    Hdfs的数据模型在对读写流程进行分析之前,我们需要先对Hdfs的数据模型有一个简单的认知。数据模型如上图所示,在NameNode中有一个唯一的FSDirectory类负责维护文件 ... [详细]
author-avatar
瘦哆哆和胖大雄
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有