gRPC概述及示例

介绍gRPC之前,让我们先简单了解一下RPC.

什么是RPC

RPC(Remote Procedure Call Protocol)——远程过程调用协议,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。RPC协议假定某些传输协议的存在,如TCP或UDP,为通信程序之间携带信息数据。在OSI网络通信模型中,RPC跨越了传输层应用层。RPC使得开发包括网络分布式多程序在内的应用程序更加容易。

RPC采用客户机/服务器模式。请求程序就是一个客户机,而服务提供程序就是一个服务器。首先,客户机调用进程发送一个有进程参数的调用信息到服务进程,然后等待应答信息。在服务器端,进程保持睡眠状态直到调用信息到达为止。当一个调用信息到达,服务器获得进程参数,计算结果,发送答复信息,然后等待下一个调用信息,最后,客户端调用进程接收答复信息,获得进程结果,然后调用执行继续进行。

工作原理(以Windows下为例)

运行时,一次客户机对服务器的RPC调用,其内部操作大致有如下十步:

1.调用客户端句柄;执行传送参数

2.调用本地系统内核发送网络消息

3.消息传送到远程主机

4.服务器句柄得到消息并取得参数

5.执行远程过程

6.执行的过程将结果返回服务器句柄

7.服务器句柄返回结果,调用远程系统内核

8.消息传回本地主机

9.客户句柄由内核接收消息

10.客户接收句柄返回的数据

GRPC

简介

gRPC 是一个高性能、开源和通用的 RPC 框架,面向移动和 HTTP/2 设计。目前提供 C、Java 和 Go 语言版本,分别是:grpc, grpc-java, grpc-go. 其中 C 版本支持 C, C++, Node.js, Python, Ruby, Objective-C, PHP 和 C# 支持.

gRPC 基于 HTTP/2 标准设计,带来诸如双向流、流控、头部压缩、单 TCP 连接上的多复用请求等特。这些特性使得其在移动设备上表现更好,更省电和节省空间占用。

gRPC 是什么?

在 gRPC 里客户端应用可以像调用本地对象一样直接调用另一台不同的机器上服务端应用的方法,使得您能够更容易地创建分布式应用和服务。与许多 RPC 系统类似,gRPC 也是基于以下理念:定义一个服务,指定其能够被远程调用的方法(包含参数和返回类型)。在服务端实现这个接口,并运行一个 gRPC 服务器来处理客户端调用。在客户端拥有一个存根能够像服务端一样的方法。

gRPC 默认使用 protocol buffers,这是 Google 开源的一套成熟的结构数据序列化机制(当然也可以使用其他数据格式如 JSON)

示例代码开发过程:

1.从官网获取问完整示例代码

1.1               使用git下载

命令:$ git clone https://github.com/grpc/grpc.git

1.2               在下载目录用VS2015打开工程

2.   定义服务

创建我们例子的第一步是定义一个服务:一个 RPC 服务通过参数和返回类型来指定可以远程调用的方法。就像你在 概览 里所看到的, gRPC 通过 protocol buffers 来实现。 我们使用 protocol buffers 接口定义语言来定义服务方法,用 protocol buffer 来定义参数和返回类型。客户端和服务端均使用服务定义生成的接口代码。 这里有我们服务定义的例子,在 helloworld.proto 里用 protocol buffers IDL 定义的。Greeter 服务有一个方法 SayHello ,可以让服务端从远程客户端接收一个包含用户名的 HelloRequest 消息后,在一个 HelloReply 里发送回一个 Greeter。这是你可以在 gRPC 里指定的最简单的 RPC - 你可以在教程里找到针对你选择的语言更多类型的例子。

syntax = "proto3";
 
option java_package = "io.grpc.examples";
 
package helloworld;
 
// The greeter service definition.
service Greeter {
 // Sends a greeting
  rpc 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;
}

3.   生成 gRPC 代码

一旦定义好服务,我们可以使用 protocol buffer 编译器 protoc 来生成创建应用所需的特定客户端和服务端的代码。生成的代码同时包括客户端的存根和服务端要实现的抽象接口,均包含 Greeter 所定义的方法。

为了生成 Windows 上的代码,我们使用来自 Google.Protobuf NuGet 包里的 protoc.exe 和来自 Grpc.Tools NuGet 包里的 Grpc.Tools ,这两个文件都在 tools 目录下。 一般你需要自己把 Grpc.Tools 包添加到解决方案,但在这个教程里,这一步已经为你做好了。你应该在 examples/csharp/helloworld 下执行以下命令:

·         Greeter/Helloworld.cs 定义了命名空间 Helloworld 它包含了所有用来填充、序列化、提取请求和应答消息类型的 protocol buffer 代码。

·         Greeter/HelloworldGrpc.cs,提供了存根类和服务类,包括:

·         一个 Greeter.IGreeter 接口,可以在定义 RootGuide 服务实现的时候来继承它。

·         一个 Greeter.GreeterClient 类,可用来访问远程的 RouteGuide 实例。

Windows下执行以下命令:

packages\Grpc.Tools.0.15.0\tools\windows_x64\protoc.exe -I../../protos --csharp_out Greeter ../../protos/helloworld.proto --grpc_out Greeter --plugin=protoc-gen-grpc=packages\Grpc.Tools.0.15.0\tools\windows_x64\grpc_csharp_plugin.exe

4.   服务实现

GreeterServer/Program.cs 实现了 Greeter 服务所需要的行为。 服务器的 GreeterImpl类,通过实现 sayHello 方法,实现了生成的IGreeter 接口:

class GreeterImpl : Greeter.IGreeter

{

public Task<HelloReply> SayHello(HelloRequest request, ServerCallContext context)

{

return Task.FromResult(new HelloReply { Message = "Hello " + request.Name });

}

}

为了返回给客户端应答并完成以下调用:

1.       用我们的消息构建并填充一个在我们接口定义的 HelloReply 应答对象。

2.       将 HelloReply 返回给客户端

5.   服务端实现

需要提供一个 gRPC 服务的另一个主要功能是让这个服务实在在网络上可用。

·         GreeterServer/Program.cs 提供了以下代码作为 C# 的例子。

·         Server server = new Server
·         {
·           Services = { Greeter.BindService(new GreeterImpl()) },
·           Ports = { new ServerPort("localhost", 50051, ServerCredentials.Insecure) }
·         };
·         server.Start();

在这里我们创建了合理的 gRPC 服务器,将我们实现的 Greeter 服务绑定到一个端口。然后我们启动服务器:服务器现在已准备好从 Greeter 服务客户端接收请求。

6.   写一个客户端

客户端的 gRPC 非常简单。在这一步,我们将用生成的代码写一个简单的客户程序来访问我们在上一节里创建的 Greeter 服务器。

6.1       连接服务

首先我们看一下我们如何连接 Greeter 服务器。我们需要创建一个 gRPC 频道,指定我们要连接的主机名和服务器端口。然后我们用这个频道创建存根实例。

Channel channel = new Channel("127.0.0.1:50051", Credentials.Insecure);

var client = Greeter.NewClient(channel);

6.2       调用 RPC

现在我们可以调用服务并获得一个 greeting :

var reply = client.SayHello(new HelloRequest { Name = user });

Console.WriteLine("Greeting: " + reply.Message);

1.       我们创建并填充一个 HelloRequest 发送给服务。

2.       我们用请求调用存根的 SayHello(),如果 RPC 成功,会得到一个填充的 HelloReply ,从其中我们可以获得 greeting。

7.   运行

7.2  启动Server端

7.2 启动Client

 

在原有实例上添加另一个服务方法

1.       打开helloworld.proto,添加如下代码:

rpc SayHelloAgain (HelloRequest) returns (HelloReply) {}

2.       使用工程中bat重新生成gRPC代码

使用windows 命令行可以执行以下命令:

packages\Grpc.Tools.0.15.0\tools\windows_x64\protoc.exe -I../../protos --csharp_out Greeter ../../protos/helloworld.proto --grpc_out Greeter --plugin=protoc-gen-grpc=packages\Grpc.Tools.0.15.0\tools\windows_x64\grpc_csharp_plugin.exe

3.       服务端实现这个新方法

public override Task<HelloReply> SayHelloAgain(HelloRequest request, ServerCallContext context)

{

return Task.FromResult<HelloReply>(new HelloReply { Message = "Hello worrld!" + request.Name });

}

4.       客户端调用此服务

var secondReply = client.SayHelloAgain(new HelloRequest { Name = user });

Console.WriteLine("Greeting: " + secondReply.Message);

5.       运行:

5.1    启动服务端监听请求

5.2    客户端远程调用服务

Client1:

Client2:

Client3:

打开Server端可以看到有多少客户端正在运行

在新服务方法上添加参数

1.       在服务定义文件helloworld.proto中添加一个参数age

2.       重新生成gRPC代码

生成之后,打开服务请求及响应类(Helloworld.cs),可以看到已自动生成Age参数。

3.       服务端重新实现服务方法

public override Task<HelloReply> SayHelloAgain(HelloRequest request, ServerCallContext context)

{

return Task.FromResult<HelloReply>(new HelloReply { Message = "Hello worrld!" +"Name:"+ request.Name+ " Age:"+request.Age });

}

}

4.           客户端修改调用方法

var secondReply = client.SayHelloAgain(new HelloRequest { Name = user,Age=age });

Console.WriteLine("Greeting: " + secondReply.Message);

5.       重新生成解决方案

6.       运行

6.1 启动服务端:

6.2 客户端调用:

由此可见,新添加的方法以生效。

如果服务方法有多个参数,客户端只传部分参数,无赋值的参数将以默认值返回。

修改客户端调用,只传入name.

客户端调用返回结果:

注意事项

用Windows命令行生成gRPC代码时,官网提供的命令不正确

packages/Grpc.Tools.1.0.0/tools/windows_x86/protoc -I../../protos --csharp_out Greeter --grpc_out Greeter ../../protos/helloworld.proto --plugin=protoc-gen-grpc=packages/Grpc.Tools.1.0.0/tools/windows_x86/grpc_csharp_plugin.exe

正确的命令如下:

packages\Grpc.Tools.0.15.0\tools\windows_x64\protoc.exe -I../../protos --csharp_out Greeter ../../protos/helloworld.proto --grpc_out Greeter --plugin=protoc-gen-grpc=packages\Grpc.Tools.0.15.0\tools\windows_x64\grpc_csharp_plugin.exe

References:

http://baike.baidu.com/link?url=xFEA9x7sw3-Rd4QYxYovY6aJ-4D6sv5sZDnLqEKclYtGFK__hl0gUVswms15pV2xNFD0swZEcCSO-w8hOt2GDnZLufANSiWLX3zHa7td6NS

http://blog.csdn.net/chszs/article/details/43908785

http://doc.oschina.net/grpc?t=56831

http://www.grpc.io/docs/

时间: 2024-10-30 06:12:14

gRPC概述及示例的相关文章

单点登录SSO:概述与示例

h1,h2 { padding-left: 2rem; color: rgb(71, 91, 204) } h1.title { font-size: 22px !important } h2.title { font-size: 18px !important } .padding { padding: 0 2rem; padding-bottom: 1rem } blockquote.menu { padding-left: 2rem; line-height: 1.8em; backgro

在Python中使用gRPC的方法示例【h】

本文介绍了在Python中使用gRPC的方法示例,分享给大家,具体如下: 使用Protocol Buffers的跨平台RPC系统. 安装 使用 pip ? 1 2 pip install grpcio pip install grpcio-tools googleapis-common-protos gRPC由两个部分构成,grpcio 和 gRPC 工具, 后者是编译 protocol buffer 以及提供生成代码的插件. 使用 编写protocol buffer 使用 gRPC 首先需要做

手把手教做单点登录(SSO)系列之一:概述与示例

本系列将由浅入深的结合示例.源码以及演示视频,手把手的带大家深入最新的单点登录SSO方案选型与架构开发实战.文末附5个满足不同单点登录场景的gif动画演示(如果看不清请在图片上右键用新窗口打开),本系列后继文章会深入它们的实现方式以及适用场景,大家也可以先观看揣摩其实现. 单点登录即Single Sign On(SSO).它是大型政府OA.企事业单位OA的标配解决方案.它概言之就是在多个Web.桌面或移动应用系统中,用户只需要登录一次,就可以访问所有的应用系统. 从业十多年,为政府.电信.跨国公

gRPC 本地服务搭建

RPC RPC 原理 主流 RPC 框架 gRPC 概述 特点 服务端创建 定义服务 生成 gRPC 代码 服务端实现 客户端实现 踩坑记录 源码 RPC RPC 原理 RPC 框架的目标就是让远程服务调用更加简单.透明,RPC 框架负责屏蔽底层的传输方式(TCP 或者 UDP).序列化方式(XML/Json/二进制)和通信细节.服务调用者可以像调用本地接口一样调用远程的服务提供者,而不需要关心底层通信细节和调用过程. RPC 框架的调用原理图: 主流 RPC 框架 支持多语言的 RPC 框架,

google多语言通信框架gRPC

google多语言通信框架gRPC系列(一)概述 gRPC概述 3/26/2016 9:16:08 AM 目录 一.概述 二.编译gRPC 三.C#中使用gRPC 四.C++中使用gRPC 一直在寻找多平台多语言的通信框架,微软的WCF框架很强大和灵活,虽然也能通过自定义绑定和其他技术的客户端通信,但是始终没有实现多平台的技术框架的统一.google的gRPC是一个不错的选择,相比于类似框架Thrift等,google的解决方案更成熟和通用.不足的是由于刚刚开源,使用范围有限,国内资料更少.例如

python 使用gRPC

Python gRPC 概述: gRPC 是谷歌开源的一个rpc(远程程序调用)框架,可以轻松实现跨语言,跨平台编程,其采用gRPC协议(基于HTTP2). rpc: remote procedure call, 翻译过来就是是远程程序调用.具体来说,就是客户端c1需要调用服务器s1上的某个方法(函数),得到相应的返回值并传递给c1. gRPC协议 要说gRPC协议需要先了解HTTP2, 虽然HTTP1.X 协议至今仍是主流协议,但是随着我们对性能要求越来越高,和web规模的不断扩大,HTTP2

gRPC入坑记

概要 由于gRPC主要是谷歌开发的,由于一些已知的原因,gRPC跑demo还是不那么顺利的.单独写这一篇,主要是gRPC安装过程中的坑太多了,记录下来让大家少走弯路. 主要的坑: 如果使用PHP.Python开发gRPC的客户端,需要编译gRPC命令行工具,生成proto的代码生成插件,否则proto里定义的service无法编译出来.编译需要使用GCC4.8级以上版本,否则报不支持C++11.然后需要龟速下周grpc源码,并下载一大堆第三方依赖.这个过程非常痛苦.使用golang.java的可

WebGL简易教程(六):第一个三维示例(使用模型视图投影变换)

目录 1. 概述 2. 示例:绘制多个三角形 2.1. Triangle_MVPMatrix.html 2.2. Triangle_MVPMatrix.js 2.2.1. 数据加入Z值 2.2.2. 加入深度测试 2.2.3. MVP矩阵设置 3. 结果 4. 参考 1. 概述 在上一篇教程<WebGL简易教程(五):图形变换(模型.视图.投影变换)>中,详细讲解了OpenGL\WebGL关于绘制场景的模型变换.视图变换以及投影变换的过程.不过那篇教程是纯理论知识,这里就具体结合一个实际的例子

第七节 继承、抽象类和接口

继承的概述 代码示例: class Person{ // 父类 String name; int age; char sex; String idcard; } class Students extends Person{ //子类 继承 父类的属性 public void study(){ System.out.println("好好学习"); } } class Worker extends Person{ //子类 继承 父类的属性 /* 我们通过继承的方式,可以省略掉Worke