当前位置: 首页 > 编程日记 > 正文

gRPC简介及简单使用(C++)

gRPC是一个现代的、开源的、高性能远程过程调用(RPC)框架,可以在任何平台运行。gRPC使客户端和服务器端应用程序能够透明地进行通信,并简化了连接系统的构建。gRPC支持的语言包括C++、Ruby、Python、Java、Go等。

gRPC默认使用Google的Protocol Buffers,关于Protocol Buffers的介绍可以参考:https://blog.csdn.net/fengbingchun/article/details/49977903

gRPC的源码在https://github.com/grpc/grpc,最新版本的版本为v1.23.0,它的license是Apache-2.0。

关于RPC(Remote Procedure Call, 远程过程调用)的介绍可以参考:https://blog.csdn.net/fengbingchun/article/details/92406377

关于gRPC的安装可以参考:https://blog.csdn.net/fengbingchun/article/details/100608370

下面参考gRPC官方examples/cpp/helloworld中的同步模式例子,过程如下:

1. 创建IDL(interface definition language)描述文件helloworld.proto,通过protobuf定义服务端与客户端之间的RPC调用接口,通过protoc工具生成客户端和服务端代码。gRPC是需要先定义服务接口约定,才可以进行RPC调用,使用.proto可以同时定义客户端和服务端交换的数据格式以及RPC调用的接口。helloworld.proto文件内容如下:

// Copyright 2015 gRPC authors.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 helloworld;// The greeting service definition.
service Greeter {// Sends a greetingrpc SayHello (HelloRequest) returns (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;
}

通过protoc工具生成服务端和客户端代码,执行命令(终端定位在demo/gRGC_Test)如下:

./../../src/grpc/linux_install/bin/protoc --cpp_out=./ helloworld.proto
./../../src/grpc/linux_install/bin/protoc --grpc_out=./ --plugin=protoc-gen-grpc=./../../src/grpc/linux_install/bin/grpc_cpp_plugin helloworld.proto

会在当前目录下生成helloworld.pb.h, hellowrold.pb.cc, helloworld.grpc.pb.h, helloworld.grpc.pb.cc四个文件。使用IDL定义服务端方法、参数、返回类型,客户端和服务端都使用从服务端定义生成的接口代码。

2. 编写客户端代码,测试代码函数为test_grpc_client;

3. 编写服务端代码,测试代码函数为test_grpc_server;

#include "funset.hpp"
#include <iostream>
#include <memory>
#include <string>
#include <grpcpp/grpcpp.h>
#include "helloworld.grpc.pb.h"// reference: grpc/examples/cpp/helloworld
namespace {class GreeterClient {
public:GreeterClient(std::shared_ptr<grpc::Channel> channel) : stub_(helloworld::Greeter::NewStub(channel)) {}// Assembles the client's payload, sends it and presents the response back from the server.std::string SayHello(const std::string& user) {// Data we are sending to the server.helloworld::HelloRequest request;request.set_name(user);// Container for the data we expect from the server.helloworld::HelloReply reply;// Context for the client. It could be used to convey extra information to the server and/or tweak certain RPC behaviors.grpc::ClientContext context;// The actual RPC.grpc::Status status = stub_->SayHello(&context, request, &reply);// Act upon its status.if (status.ok()) {return reply.message();} else {fprintf(stderr, "error code: %d, error message: %s\n", status.error_code(), status.error_message().c_str());return "RPC failed";}	}	private:std::unique_ptr<helloworld::Greeter::Stub> stub_;
};} // namespaceint test_grpc_client()
{fprintf(stdout, "client start\n");// 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't authenticated(use of InsecureChannelCredentials()).GreeterClient greeter(grpc::CreateChannel("localhost:50051", grpc::InsecureChannelCredentials()));std::string user("world");std::string reply = greeter.SayHello(user);fprintf(stdout, "Greeter received: %s\n", reply.c_str());return 0;
}namespace {// Logic and data behind the server's behavior.
class GreeterServiceImpl final : public helloworld::Greeter::Service {grpc::Status SayHello(grpc::ServerContext* context, const helloworld::HelloRequest* request, helloworld::HelloReply* reply) override {std::string prefix("Hello ");reply->set_message(prefix + request->name());return grpc::Status::OK;}
};void RunServer() {std::string server_address("0.0.0.0:50051");GreeterServiceImpl service;grpc::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'll communicate with clients.// In this case it corresponds to an *synchronous* service.builder.RegisterService(&service);// Finally assemble the server.std::unique_ptr<grpc::Server> server(builder.BuildAndStart());fprintf(stdout, "Server listening on: %s\n", server_address.c_str());// 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();
}} // namespaceint test_grpc_server()
{fprintf(stdout, "server start\n");RunServer();return 0;
}

4. 先在一个终端启动服务端程序,再在另一个终端启动客户端程序,执行结果如下:

GitHub:https://github.com/fengbingchun/OpenSSL_Test

相关文章:

YC中国被撤,陆奇独立运营个人新品牌「奇绩创坛」

整理 | Jane出品 | AI科技大本营&#xff08;ID&#xff1a;rgznai100&#xff09;近日&#xff0c;Y Combinator&#xff08;以下简称 YC&#xff09; 发布消息称&#xff0c;YC 将撤回 YC 中国业务与运营&#xff0c;这一品牌也将停止使用&#xff0c;YC的战略布局将调整重新…

shell 脚本逐行读取多个文件,并逐行对应

#!/bin/bashfor i in seq 448doaaased -n "$i"p num.txtbbbsed -n "$i"p text.txt/root/cooper/sms.pl $aaa $bbbdonenum.txt 记录了348个号码text.txt中记录了348个字段效果是取num.txt中第一行作为第一行参数 取text.txt中第一行作为第二个参数num.txt要…

iOS常用知识点1

多线程、特别是NSOperation 和 GCD 的内部原理。 运行时机制的原理和运用场景。 SDWebImage的原理。实现机制。如何解决TableView卡的问题。 block和代理的&#xff0c;通知的区别。block的用法需要注意些什么。 strong&#xff0c;weak&#xff0c;retain&#xff0c;assign&a…

美团BERT的探索和实践 | CSDN原力计划

扫码参与CSDN“原力计划”作者 | 杨扬 佳昊 金刚等来源 | CSDN原力计划作品*点击阅读原文&#xff0c;查看美团技术团队更多干货文章。背景2018年&#xff0c;自然语言处理&#xff08;Natural Language Processing&#xff0c;NLP&#xff09;领域最激动人心的进展莫过于预训练…

程序员的自我修养--链接、装载与库笔记:可执行文件的装载与进程

可执行文件只有装载到内存以后才能被CPU执行。 1. 进程虚拟地址空间 程序和进程有什么区别&#xff1a;程序(或者狭义上讲可执行文件)是一个静态的概念&#xff0c;它就是一些预先编译好的指令和数据集合的一个文件&#xff1b;进程则是一个动态的概念&#xff0c;它是程序运…

JDBC实例--工具类升级,使用Apache DBCP连接池重构DBUtility,让连接数据库更有效,更安全...

直接使用JDBC访问数据库时&#xff0c;需要避免以下隐患: 1. 每一次数据操作请求都需要建立数据库连接、打开连接、存取数据和关闭连接等步骤。而建立和打开数据库连接是一件既耗资源又费时的过程&#xff0c;如果频繁发生这种数据库操作&#xff0c;势必会使系统性能下降。 2.…

程序员的自我修养--链接、装载与库笔记:Linux共享库的组织

共享库(Shared Library)概念&#xff1a;其实从文件结构上来讲&#xff0c;共享库和共享对象没什么区别&#xff0c;Linux下的共享库就是普通的ELF共享对象。由于共享对象可以被各个程序之间共享&#xff0c;所以它也就成为了库的很好的存在形式&#xff0c;很多库的开发者都以…

iOS下JS与原生OC互相调用

iOS开发免不了要与UIWebView打交道&#xff0c;然后就要涉及到JS与原生OC交互&#xff0c;今天总结一下JS与原生OC交互的两种方式。 JS调用原生OC篇 方式一 第一种方式是用JS发起一个假的URL请求&#xff0c;然后利用UIWebView的代理方法拦截这次请求&#xff0c;然后再做相…

马斯克发首款会上火星的电动皮卡:28万起,可防弹,造型相当“赛博朋克”...

整理 | Jane、非主流出品 | AI科技大本营&#xff08;ID&#xff1a;rgznai100&#xff09;【导读】马斯克今日发布酝酿多年、“真爱系列”的第一辆电动皮卡Cybertruck&#xff0c;Cybertruck 是赛博朋克&#xff08;cyberpunk&#xff09;与卡车&#xff08;truck&#xff09;…

让你提升命令行效率的 Bash 快捷键

为什么80%的码农都做不了架构师&#xff1f;>>> 原文&#xff1a;http://linuxtoy.org/archives/bash-shortcuts.html 生活在 Bash shell 中&#xff0c;熟记以下快捷键&#xff0c;将极大的提高你的命令行操作效率。 编辑命令 Ctrl a &#xff1a;移到命令行首Ct…

程序员的自我修养--链接、装载与库笔记:Windows下的动态链接

Windows下的PE的动态链接与Linux下的ELF动态链接相比&#xff0c;有很多类似的地方&#xff0c;但也有很多不同的地方。 1. DLL简介 DLL即动态链接库(Dynamic-Link Library)的缩写&#xff0c;它相当于Linux下的共享对象。Windows系统中大量采用了这种DLL机制&#xff0c;甚至…

iOS下JS与OC互相调用(一)--UIWebView 拦截URL

1.在JS 中做一次URL跳转&#xff0c;然后在OC中拦截跳转。&#xff08;这里分为UIWebView 和 WKWebView两种&#xff0c;去年因为还要兼容iOS 6&#xff0c;所以没办法只能采用UIWebView来做。&#xff09;2.利用WKWebView 的MessageHandler。3.利用系统库JavaScriptCore&#…

AI换脸鉴别率超99.6%,微软用技术应对虚假信息

来源 | 微软亚洲研究院AI头条&#xff08;ID:MSRAsia&#xff09;近日社交网络上爆红的一款换脸应用&#xff0c;让许多普通用户体验到了跟爱豆同框、与偶像飙戏的快乐&#xff0c;也因数据使用带来的问题陷入了舆论的漩涡——除了用户隐私保障&#xff0c;如何辨别和处理换脸应…

使用Apache Tiles3.x构建界面布局(一)

Tiles是一个免费的开源模板Java应用程序的框架。基于复合模式简化的用户界面的构建。对于复杂的网站仍是最简单、最优雅的方式与任何MVC技术一起工作。Struts2对Tiles提供了支持&#xff0c;如今Tiles发展已有13个年头&#xff0c;成为Apache的一个独立项目&#xff0c;我们可以…

iOS下JS与OC互相调用(二)--WKWebView 拦截URL

在上篇文章中讲述了使用UIWebView拦截URL的方式来处理JS与OC交互。 由于UIWebView比较耗内存&#xff0c;性能上不太好&#xff0c;而苹果在iOS 8中推出了WKWebView。 同样的用WKWebView也可以拦截URL&#xff0c;做JS 与OC交互。关于WKWebView与UIWebView的对比&#xff0c;大…

基于模型的强化学习比无模型的强化学习更好?错!

作者 | Carles Gelada and Jacob Buckman编辑 | DeepRL来源 | 深度强化学习实验室&#xff08;ID:Deep-RL)【导读】许多研究人员认为&#xff0c;基于模型的强化学习&#xff08;MBRL&#xff09;比无模型的强化学习&#xff08;MFRL&#xff09;具有更高的样本效率。但是&…

程序员的自我修养--链接、装载与库笔记:内存

1. 程序的内存布局 现代的应用程序都运行在一个内存空间里&#xff0c;在32位的系统里&#xff0c;这个内存空间拥有4GB(2的32次方)的寻址能力。应用程序可以直接使用32位的地址进行寻址&#xff0c;这被称为平坦(flat)的内存模型。在平坦的内存模型中&#xff0c;整个内存是一…

【Away3D代码解读】(四):主要模块简介

数据模块&#xff1a; Away3D中最核心的数据类是Mesh类&#xff0c;我们先看看Mesh类的继承关系&#xff1a; NamedAssetBase&#xff1a;为对象提供id和name属性&#xff0c;是Away3D大部分类的基类&#xff1b; Object3D&#xff1a;3D对象基类&#xff0c;提供方便操作3D对象…

程序员的自我修养--链接、装载与库笔记:运行库

1. 入口函数和程序初始化 程序从main开始吗&#xff1f;&#xff1a;操作系统装载程序之后&#xff0c;首先运行的代码并不是main的第一行&#xff0c;而是某些别的代码&#xff0c;这些代码负责准备好main函数执行所需要的环境&#xff0c;并且负责调用main函数&#xff0c;这…

iOS下JS与OC互相调用(三)--MessageHandler

使用WKWebView的时候&#xff0c;如果想要实现JS调用OC方法&#xff0c;除了拦截URL之外&#xff0c;还有一种简单的方式。那就是利用WKWebView的新特性MessageHandler来实现JS调用原生方法。 MessageHandler 是什么&#xff1f; WKWebView 初始化时&#xff0c;有一个参数叫…

北大教授张大庆:无线感知,让你变老也优雅

受访者 | 张大庆记者 | 胡巍巍出品 | CSDN&#xff08;ID&#xff1a;CSDNnews&#xff09;在国内高校中&#xff0c;北大的校庆日很特殊——5月4日。这一天&#xff0c;也是青年节。北大&#xff0c;是五四运动的策源地。100年来&#xff0c;“爱国、进步、民主、科学”的五四…

总结 20 个开发细节

2019独角兽企业重金招聘Python工程师标准>>> 1&#xff1a;提交到SVN的代码必须有提交备注&#xff0c;以便于以后查看。 2&#xff1a;如考虑页面缓存&#xff0c;可以在路径后增加随机数&#xff1a;url "&TimeS" Math.random();。 3&#xff1a;…

程序员的自我修养--链接、装载与库笔记:系统调用与API

系统调用(System Call)是应用程序(运行库也是应用程序的一部分)与操作系统内核之间的接口&#xff0c;它决定了应用程序是如何与内核打交道的。无论程序是直接进行系统调用&#xff0c;还是通过运行库&#xff0c;最终还是会到达系统调用这个层面上。 1. 系统调用介绍 什么是…

iOS下JS与OC互相调用(四)--JavaScriptCore

前面讲完拦截URL的方式实现JS与OC互相调用&#xff0c;终于到JavaScriptCore了。它是从iOS7开始加入的&#xff0c;用 Objective-C 把 WebKit 的 JavaScript 引擎封装了一下&#xff0c;提供了简单快捷的方式与JavaScript交互。 关于JavaScriptCore的使用有两篇很好的文章&…

围巾都这么黑科技了,是我见识少了

有一个永恒的话题&#xff1a;北方冷一点还是南方冷一点&#xff1f;答案是&#xff1a;哪里都冷&#xff01;冬天最痛苦的莫过于走出空调房——刺骨的风直直的从领口处灌进去那叫一个“透心凉&#xff0c;心飞扬”缠了好几圈的大围巾却根本没什么保暖效果每当这时候&#xff0…

【教程】【FLEX】#004 反射机制

总结&#xff1a; 目前用到反射的主要有两个方法 1. getDefinitionByName //根据类名&#xff0c;返回对象&#xff08;反射实例化对象&#xff09; 2. describeType //根据对象&#xff0c;返回XML格式的属性&#xff0c;方法等信息&#xff08;反射得到…

iOS下JS与OC互相调用(五)--UIWebView + WebViewJavascriptBridge

WebViewJavascriptBridge是一个有点年代的JS与OC交互的库&#xff0c;使用该库的著名应用还挺多的&#xff0c;目前这个库有7000star。我去翻看了它的第一版本已经是4年前了&#xff0c;在版本V4.1.4以及之前&#xff0c;该库只有一个类和一个js 的txt文件&#xff0c;所以旧版…

OpenCV代码提取:Windows上通过DShow获取Camera视频

在OpenCV 3.1中获取视频的模块在videoio(video input and output module)中&#xff0c;调用VideoCapture类接口&#xff0c;除了videoio模块外还依赖core、highgui、imgproc、imgcodecs四个模块&#xff0c;而OpenCV 2.4.13.6仅需要core、highgui、imgproc三个模块。3.1中的vi…

迁移学习与图神经网络“合力”模型:用DoT-GNN克服组重识别难题

作者 | Ziling Huang、Zheng Wang、Wei Hu、Chia-Wen Lin、Shin’ichi Satoh译者 | 刘畅编辑 | Jane出品 | AI科技大本营&#xff08;ID&#xff1a;rgznai100&#xff09;【导读】目前&#xff0c;大多数行人重识别&#xff08;ReID&#xff09;方法主要是从收集的单个人图像数…

struts2 select 默认选中

jsp:<s:select list"#{1:男,2:女}" name"sex"/> action:private String sex;sex属性有get/set方法。在业务方法中设置sex "2";select会默认选中。