gRpc原理解析及C#中使用示例

目录

概述

使用场景

gRpc使用示例

创建解决方案

定义.proto文件

proto文件编译

实现服务代码

调用远程服务

RPC远程调用测试


概述

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 一开始由 google 开发,是一款语言中立、平台中立、开源的远程过程调用(RPC)系统。

所谓RPC(remote procedure call 远程过程调用)框架实际是提供了一套机制,使得应用程序之间可以进行通信,而且也遵从server/client模型。使用的时候客户端调用server端提供的接口就像是调用本地的函数一样。如下图所示就是一个典型的RPC结构图。

gRpc原理解析及C#中使用示例_第1张图片

使用场景

  • 需要对接口进行严格约束的情况,比如我们提供了一个公共的服务,很多人,甚至公司外部的人也可以访问这个服务,这时对于接口我们希望有更加严格的约束,我们不希望客户端给我们传递任意的数据,尤其是考虑到安全性的因素,我们通常需要对接口进行更加严格的约束。这时gRPC就可以通过protobuf来提供严格的接口约束。
  • 对于性能有更高的要求时。有时我们的服务需要传递大量的数据,而又希望不影响我们的性能,这个时候也可以考虑gRPC服务,因为通过protobuf我们可以将数据压缩编码转化为二进制格式,通常传递的数据量要小得多,而且通过http2我们可以实现异步的请求,从而大大提高了通信效率。

gRpc使用示例

gRPC的使用通常包括如下几个步骤:

  1. 通过Protocol Buffer来定义接口和数据类型
  2. 通过Protocol Buffer编译器编译proto文件为对应平台的代码文件
  3. 编写gRPC server端代码
  4. 编写gRPC client端代码

下面以C#为例介绍gRpc的使用流程:

创建解决方案

分别新建gRpcDemo C#类库,gRpcService、gRpcClient控制台应用程序,项目结构如下:

gRpc原理解析及C#中使用示例_第2张图片

项目gRpcDemo中包含.proto文件及protocol buffer 生成文件,生成C#代码文件可在gRpcService和gRpcClient中访问对应接口及服务代码实现。本示例服务端和客户端采用相同的语言,如果平台语言一致需要分别生成对应的代码文件到项目中。

定义.proto文件

定义文件LogService.proto文件(文本文件直接编辑在更改文件名)

syntax = "proto3";		//指定语法proto2或proto3 本文采用proto3

//package gRpcDemo;		//指定命名空间
option csharp_namespace = "gRpcDemo";

//定义rpc服务
service gRpcQueryService
{
	rpc Search(QureyCond) returns (QueryResult);
}
//定义查询条件消息体
message QureyCond
{
	int32 id=1;		//通过id查询		
}
//定义查询结果实体对象
message QueryResult
{
	int32 id=1;		
	string name=2;		
	int32 age=3;	
}

proto文件编译

添加工具包

右键点击“解决方案gRpc”,点击“管理解决方案的NuGet程序包”,在浏览中分别搜索"Grpc"、"Grpc.Tools"、"Google.Protobuf",然后点击右面项目,全选,再点击安装

gRpc原理解析及C#中使用示例_第3张图片

编译proto文件

在项目packages文件夹(*\packages\grpc.tools\2.25.0-pre1\tools\windows_x64)下找到protoc.exe和grpc_csharp_plugin.exe(如果项目文件夹下没有packages就新建,并将上面找到的.nuget\packages中的“Google.protobuf”、“grpc”、“grpc.tools”文件夹拷贝到我们工程文件夹下的packages里面)。

在dos下使用proto编译器执行命令:

gRpc原理解析及C#中使用示例_第4张图片

  • -I:设定源路径
  • --csharp_out::编译文件的输出路径,如果使用其它语言请使用对应语言的option
  • --grpc_out:设定输出路径
  • --plugin:设定编译需要的插件
  • proto文件:需要编译的服务定义文件

编译成功后在输出目录会生成两个文件,然后添加到gRpcDemo项目中:

gRpc原理解析及C#中使用示例_第5张图片

完成后编译gRpcDemo类库,然后添加项目引用到gRpcService和gRpcClient中。

实现服务代码

在项目gRpcServer项目中实现服务逻辑:

namespace gRpcServer
{
    class Program
    {
        const int Port = 8050;

        public static void Main(string[] args)
        {
            Server server = new Server
            {
                Services = { gRpcQueryService.BindService(new GRPCImpl()) },
                Ports = { new ServerPort("localhost", Port, ServerCredentials.Insecure) }
            };
            server.Start();

            Console.WriteLine("gRPC server listening on port " + Port);
            Console.WriteLine("任意键退出...");
            Console.ReadKey();

            server.ShutdownAsync().Wait();
        }
    }

    class GRPCImpl :gRpcQueryService.gRpcQueryServiceBase
    {
        public override Task Search(QureyCond request, ServerCallContext context)
        {
            return Task.FromResult(Search(request));
        }

        private QueryResult Search(QureyCond cond)
        {
            //自定义逻辑
            QueryResult result = new QueryResult();
            result.Id = cond.Id;
            result.Name = "张三";
            result.Age = 20;
            return result;
        }
    }
}

调用远程服务

在项目gRpcClient项目中实现调用服务逻辑:

namespace gRpcClient
{
    class Program
    {
        static void Main(string[] args)
        {
            Channel channel = new Channel("127.0.0.1:8050", ChannelCredentials.Insecure);

            var client = new gRpcQueryService.gRpcQueryServiceClient(channel);
            var result = client.Search(new QureyCond { Id = 2 });
            Console.WriteLine("结果:id={0} name={1} age={2}", result.Id, result.Name, result.Age);

            channel.ShutdownAsync().Wait();

            Console.WriteLine("任意键退出...");
            Console.ReadKey();
        }
    }
}

RPC远程调用测试

分别运行gRpcServer和gRpcClient查看远程调用结果:

gRpc原理解析及C#中使用示例_第6张图片

远程服务调用成功!

项目源码:https://download.csdn.net/download/uiuan00/11945481

项目源码(含RPC流式方法):https://download.csdn.net/download/uiuan00/14068609

你可能感兴趣的:(网络通讯,gRPC,protocol,buffer)