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就可以通過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控制檯應用程序,項目結構如下:

項目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",然後點擊右面項目,全選,再點擊安裝

編譯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編譯器執行命令:

  • -I:設定源路徑
  • --csharp_out::第一個參數設定編譯文件的路徑,第二個參數設定需要編譯的proto文件;如果使用其它語言請使用對應語言的option
  • --grpc_out:設定輸出路徑
  • --plugin:設定編譯需要的插件

編譯成功後在輸出目錄會生成兩個文件,然後添加到gRpcDemo項目中:

完成後編譯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<QueryResult> 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查看遠程調用結果:

遠程服務調用成功!

項目源碼:https://download.csdn.net/download/uiuan00/11945481

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章