<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          工作多年:一文看懂.NET gRPC!

          共 8241字,需瀏覽 17分鐘

           ·

          2021-03-19 12:42

              gRPC是高性能的RPC框架, 有效地用于服務(wù)通信(不管是數(shù)據(jù)中心內(nèi)部還是跨數(shù)據(jù)中心)。

          由Google開源,目前是一個(gè)Cloud Native Computing Foundation(CNCF)孵化項(xiàng)目。

          其功能包括:

          ?雙向流?強(qiáng)大的二進(jìn)制序列化?可插拔的身份驗(yàn)證,負(fù)載平衡和運(yùn)行狀況檢查

          在gRPC中,客戶端應(yīng)用程序可以直接在A服務(wù)器上調(diào)用B服務(wù)器的方法,就好像它是本地對(duì)象一樣,從而使您更輕松地創(chuàng)建分布式應(yīng)用程序和微服務(wù)。

          與許多RPC系統(tǒng)一樣,gRPC也是圍繞著定義服務(wù)的思想(定義可遠(yuǎn)程調(diào)用方法的入?yún)⒑头祷刂殿愋?。

          在服務(wù)端,服務(wù)端實(shí)現(xiàn)此接口并運(yùn)行g(shù)RPC服務(wù)器,以處理客戶端調(diào)用。
          在客戶端,客戶端有一個(gè)存根,提供與服務(wù)器相同的方法。

          在本文中,我將向您展示如何使用.NET5創(chuàng)建gRPC服務(wù)。我將分解gRPC的一些重要基礎(chǔ)概念,并給出一個(gè)有意思的包羅核心功能的實(shí)例。

          1.創(chuàng)建一個(gè)gRPC服務(wù)器

          我們從gRPC服務(wù)模板創(chuàng)建一個(gè)新的dotnet項(xiàng)目。

          如果使用Visual Studio,請(qǐng)創(chuàng)建一個(gè)新項(xiàng)目,然后選擇gRPC Service模板,使用GrpcAuthor作為項(xiàng)目的名稱。

          1.1  定義Rpc 服務(wù)

          客戶端與服務(wù)端使用protocol buffers交流/通信:
          protocol buffers既用作服務(wù)的接口定義語言(IDL),又用作底層消息交換格式

          ① 使用protocol buffers在.proto文件中定義服務(wù)接口。在其中,定義可遠(yuǎn)程調(diào)用的方法的入?yún)⒑头祷刂殿愋停?wù)端實(shí)現(xiàn)此接口并運(yùn)行g(shù)RPC服務(wù)器以處理客戶端調(diào)用。
          ② 定義服務(wù)后,使用protocol buffers編譯器protoc從.proto文件生成數(shù)據(jù)訪問/傳輸類,該文件包含服務(wù)接口中消息和方法的實(shí)現(xiàn)。

          關(guān)注VS腳手架項(xiàng)目Protos文件夾中的greet.proto。

          syntax = "proto3";option csharp_namespace = "GrpcAuthor";package greet;// The greeting 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;}

          從.proto文件內(nèi)容上大致知道服務(wù)功能 (給某人一個(gè)回應(yīng)), 這里提示一些語法:

          syntax指示使用的protocol buffers的版本。在這種情況下,proto3是撰寫本文時(shí)的最新版本。csharp_namespace指示生成的文件所在的命名空間package說明符也是這個(gè)作用,用于防止協(xié)議消息類型之間的名稱沖突。

          對(duì)于C#,如果提供選項(xiàng)csharp_namespace,csharp_namespace值將用作命名空間;
          在Java中,如果提供選項(xiàng)java_package,java_package將用作包名稱。

              ③service Greeter定義服務(wù)基類名稱, rpc SayHello (HelloRequest) returns (HelloReply); 是一個(gè)一元rpc調(diào)用    ④HelloRequestHelloReply是在客戶端和服務(wù)器之間交換信息的數(shù)據(jù)結(jié)構(gòu)。它們被稱為消息
          你在消息字段中定義的數(shù)字是不可重復(fù)的,當(dāng)消息被序列化為Protobuf時(shí),該數(shù)字用于標(biāo)識(shí)字段,這是因?yàn)樾蛄谢粋€(gè)數(shù)字比序列化整個(gè)字段名稱要快。

          1.2 實(shí)現(xiàn)服務(wù)接口

               為了從.proto文件生成代碼,可以使用protoc編譯器和C#插件來生成服務(wù)器或客戶端代碼。
          腳手架項(xiàng)目使用Grpc.AspNetCore NuGet包:所需的類由構(gòu)建過程自動(dòng)生成, 你只需要在項(xiàng)目.csproj文件中添加 配置節(jié):

          <ItemGroup>  <Protobuf Include="Protos\greet.proto" GrpcServices="Server" /></ItemGroup>

          生成的代碼知道如何使用protocol buffers與其他服務(wù)/客戶端進(jìn)行通信。

          C#工具生成GreeterBase類型,將用作實(shí)現(xiàn)gRPC服務(wù)的基類。

          public class GreeterService : Greeter.GreeterBase{    private readonly ILogger<GreeterService> _logger;    public GreeterService(ILogger<GreeterService> logger)    {        _logger = logger;    }    public override Task<HelloReply> SayHello(HelloRequest request, ServerCallContext context)    {        return Task.FromResult(new HelloReply        {            Message = "Hello " + request.Name        });    }}

          最后注冊(cè)Grpc端點(diǎn)endpoints.MapGrpcService<GreeterService >();

          --- 啟動(dòng)服務(wù)---...

          2. 創(chuàng)建gRPC .NET控制臺(tái)客戶端

          Visual Studio創(chuàng)建一個(gè)名為GrpcAuthorClient的新控制臺(tái)項(xiàng)目。

          安裝如下nuget包:
          Install-Package Grpc.Net.Client
          Install-Package Google.Protobuf
          Install-Package Grpc.Tools

          Grpc.Net.Client包含.NET Core客戶端;
          Google.Protobuf包含protobuf消息API;
          Grpc.Tools對(duì)Protobuf文件進(jìn)行編譯。

          拷貝服務(wù)端項(xiàng)目中的.proto文件將選項(xiàng)csharp_namespace值修改為GrpcAuthorClient。更新.csproj文件的 配置節(jié)

          <ItemGroup>    <Protobuf Include="Protos\greet.proto" GrpcServices="Client" />  </ItemGroup>

              ④Client主文件:

          static void Main(string[] args){      var serverAddress = "https://localhost:5001";      using var channel = GrpcChannel.ForAddress(serverAddress);      var client = new Greeter.GreeterClient(channel);      var reply = client.SayHello(new HelloRequest { Name = "宋小寶!" });
          Console.WriteLine(reply.Message.ToString());
          Console.WriteLine("Press any key to exit..."); Console.ReadKey();}


          使用服務(wù)器地址創(chuàng)建GrpcChannel,使用GrpcChannel對(duì)象實(shí)例化GreeterClient;

          然后使用SayHello同步方法; 打印服務(wù)器響應(yīng)結(jié)果。

          3. 其他核心功能

          3.1  通信方式

          • Unary RPC(一元Rpc調(diào)用): 上面的例子

          • Server streaming RPC :服務(wù)器流式RPC,客戶端在其中向服務(wù)器發(fā)送請(qǐng)求,并讀取消息流。客戶端從返回的流中讀取,直到?jīng)]有更多消息為止。gRPC保證單個(gè)RPC調(diào)用中的消息順序。

          • Client streaming RPC:客戶端流式RPC,客戶端使用流,寫入一系列消息并發(fā)送到服務(wù)器。客戶端寫完消息后,它將等待服務(wù)器讀取消息并返回響應(yīng)。同樣,gRPC保證了單個(gè)RPC調(diào)用中的消息順序。

          • Bidirectional streaming RPC:雙向流式通信,由于兩個(gè)流是獨(dú)立的,因此客戶端和服務(wù)器可以按任何順序讀取和寫入消息。例如,服務(wù)器可以等到收到客戶端的所有消息后再寫消息,或者服務(wù)器和客戶端可以打“乒乓” (服務(wù)器收到請(qǐng)求,然后響應(yīng)消息,然后客戶端基于響應(yīng)發(fā)送另一個(gè)消息,依此往返)

          3.2 Metadata

                 元數(shù)據(jù)是以鍵值對(duì)列表的形式提供的有關(guān)特定RPC調(diào)用的信息(例如身份驗(yàn)證詳細(xì)信息),其中鍵是字符串,值通常是字符串,但可以是二進(jìn)制數(shù)據(jù)。元數(shù)據(jù)對(duì)于gRPC本身是不透明的:它允許客戶端向服務(wù)器提供與調(diào)用相關(guān)的信息,反之亦然。

          3.3  Channels

                  gRPC通道提供到指定主機(jī)和端口上的gRPC服務(wù)器的連接。
          創(chuàng)建客戶端存根時(shí)用到它,可以指定通道參數(shù)來修改gRPC的默認(rèn)行為,例如打開或關(guān)閉消息壓縮。
          通道具有狀態(tài),包括已連接和空閑。


          4. gRpc打乒乓球

          針對(duì)腳手架項(xiàng)目,稍作修改--->乒乓球局

          (考察gRpc雙向流式通信、Timeout機(jī)制、異常處理):  

          客戶端發(fā)送"gridsum",  服務(wù)端回發(fā)"musdirg";  客戶端再發(fā)送"gridsum", 往復(fù)......

          ① 添加接口

          rpc PingPongHello(stream HelloRequest) returns (stream HelloReply);

          ② 實(shí)現(xiàn)服務(wù)契約

          try{    while (!context.CancellationToken.IsCancellationRequested)    {         var asyncRequests = requestStream.ReadAllAsync();         // 客戶端與服務(wù)端"打乒乓"         await foreach (var req in asyncRequests)         {               var send = Reverse(req.Name);               await responseStream.WriteAsync(new HelloReply               {                   Message = send,                   Id = req.Id +1               });               Debug.WriteLine($"第{req.Id}回合,服務(wù)端收到 {req.Name};開始第{req.Id + 1}回合,服務(wù)端回發(fā) {send}");          }     }}catch(RpcException ex){      System.Diagnostics.Debug.WriteLine($"{ex.Message}");}

           ③ 客戶端代碼,控制乒乓球局在5s后終止

          using (var cancellationTokenSource = new CancellationTokenSource( 5* 1000)){     try     {          var duplexMessage = client.PingPongHello(null, null, cancellationTokenSource.Token);          await duplexMessage.RequestStream.WriteAsync(new HelloRequest { Id = 1, Name = "gridsum" }) ;
                    var asyncResp = duplexMessage.ResponseStream.ReadAllAsync(); await foreach (var resp in asyncResp) { var send = Reverse(resp.Message);                await duplexMessage.RequestStream.WriteAsync(new HelloRequest {Id= resp.Id, Name = send }); Console.WriteLine($"第{resp.Id}回合,客戶端收到 {resp.Message}, 客戶端發(fā)送{send}");          } }       catch (RpcException ex)       {           Console.WriteLine("打乒乓球時(shí)間到了(客戶端5s后終斷gRpc連接)");       } }

          https://github.com/zaozaoniao/GrpcAuthor

          總結(jié)

               gRPC是具有可插拔身份驗(yàn)證和負(fù)載平衡功能的高性能RPC框架。
          使用protocol buffers定義結(jié)構(gòu)化數(shù)據(jù);使用不同語言自動(dòng)產(chǎn)生的源代碼在各種數(shù)據(jù)流中寫入和讀取結(jié)構(gòu)化數(shù)據(jù)。

          在本文中,您學(xué)習(xí)了如何使用protocol buffers 定義服務(wù)接口以及如何使用C#實(shí)現(xiàn)服務(wù)。最后,您使用gRPC雙向流式通信創(chuàng)建了 "打乒乓球"Demo。

          Additional Resources

          ?  https://developers.google.com/protocol-buffers/docs/csharptutorial?  https://www.grpc.io/docs/what-is-grpc/core-concepts/?  https://docs.microsoft.com/en-us/dotnet/architecture/grpc-for-wcf-developers/why-grpc







          回復(fù) 【關(guān)閉】學(xué)關(guān)
          回復(fù) 【實(shí)戰(zhàn)】獲取20套實(shí)戰(zhàn)源碼
          回復(fù) 【被刪】學(xué)個(gè)
          回復(fù) 【訪客】學(xué)
          回復(fù) 【小程序】學(xué)獲取15套【入門+實(shí)戰(zhàn)+賺錢】小程序源碼
          回復(fù) 【python】學(xué)微獲取全套0基礎(chǔ)Python知識(shí)手冊(cè)
          回復(fù) 【2019】獲取2019 .NET 開發(fā)者峰會(huì)資料PPT
          回復(fù) 【加群】加入dotnet微信交流群

          強(qiáng)烈推薦:超全C#幫助類,提升效率就靠它


          @所有人,20個(gè)Q幣,趕快領(lǐng)取!


          瀏覽 83
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  爱伊人久久 | 国产精品―色哟呦 | 久久久蜜桃视频 | 秋霞午夜成人无码精品 | 欧洲福利视频 |