成人在线亚洲_国产日韩视频一区二区三区_久久久国产精品_99国内精品久久久久久久

您的位置:首頁技術文章
文章詳情頁

.NET Core中使用gRPC的方法

瀏覽:371日期:2022-06-08 10:55:41
目錄
  • 1.什么是gRPC
    • 1.基本介紹
    • 2.proto文件
    • 3.上手實踐
  • 2.gRPC流
    • 1.服務端流、客戶端流、雙向流
    • 2.NetCore Web項目作為客戶端
  • 3.gRPC AOP攔截

    1.什么是gRPC

    1.基本介紹

    gRPC 一開始由 google 開發,是一款語言中立、平臺中立、開源的遠程過程調用(RPC)系統,所以叫g(google)RPC。支持主流開發語言(C, C++, Python, PHP, Ruby, NodeJS, C#, Objective-C、Golang

    2.proto文件

    用于定義協議接口和數據格式,不同的語言,相同的文件,可以理解為一項約定,序列化支持 PB(Protocol buffer)和 JSON,PB 是一種語言無關的高性能序列化框架,基于 HTTP/2 + PB, 保障了 RPC 調用的高性能。

    說這么多感覺還是很模糊,上面只是介紹了gRPC是什么,在我看來其實它大致的作用跟WebServicesWCF差不多,在某個維度上可以說都是作為遠程調用,只不過所處的時代和本身的特性,以及生態的發展下,導致它成為目前比較火熱的原因之一,具體的內容后面再討論,先用起來,再深入了解,接下來我們使用.Net Core 先搭建一個簡單的Demo,來親自上手實踐一下。

    其實背景就是最近在做一個項目,需要做一個公司內部的Nuget包,大概的業務就是Nuget包請求微服務數據,開始想直接使用http的方式,基于整體項目結構后面定了使用gRPC,既學即用,剛好也可以在實際項目應用中,查漏補缺。

    3.上手實踐

    1.使用vs首先創建一個NetCore gRPC項目,得到一個項目結構如下,框架默認包含一個已經預先定義協議文件服務接口,如果使用其他的方式也很簡單直接引用相關的包,然后添加以下服務就可以了

    2.我們自己創建一個自己的接口,定義一個協議文件mytestdemo.proto,然后定義一些方法,主要包含如下幾類,其他的一些用法可以在網上搜到,或者去看文檔,只是簡單列一下

    1.有參數有返回值

    2.無參數有返回值 ,無參使用google.protobuf.Empty

    3.集合作為返回值,必須使用repeated 標記

    如果你真的不熟悉protobuf的定義方式和寫法,這個無傷大雅,可以使用工具生成

    syntax = "proto3";//引入集合包import "google/protobuf/empty.proto";//命名空間option csharp_namespace = "GrpcDemo";//包名package MyTest;//接口定義service MyTestDemo {  rpc MultipleParam(MultipleRequestPara) returns (MultipleRespone);  rpc NoParam(google.protobuf.Empty) returns (SingeRespone);  rpc CollectionParam(google.protobuf.Empty) returns (CollectionResponePara);}//多參數請求參數message MultipleRequestPara {  int32 Id = 1;  string Name = 2;//參數個數  bool IsExists =3;}message SingeRespone {  bool Success =1;  TestEntity a1 = 2;  message TestEntity{	int32 Id =1;  }}//多參數返回message MultipleRespone {	bool Success =1;}//返回集合參數message CollectionResponePara {	repeated CollectionChildrenRespone1 param1 =1;	repeated CollectionChildrenRespone2 param2 =2;	repeated int32 param3 =3;}//集合屬性1message CollectionChildrenRespone1 {	int32 Id =1;}//集合屬性2message CollectionChildrenRespone2 {	string Name =1;	}

    3.右鍵類,選擇添加,選擇連接的服務,添加gRPC,或者直接修改項目文件,將新建的proto添加到類中

    3.1 重新生成,然后創建服務代碼MyTestService,如下代碼
    3.2 在啟動類中映射gRPC app.MapGrpcService<MyTestService>(); 否則會報service is unimplemented.

    /// <summary>/// 繼承自MyTestDemo.MyTestDemoBase/// </summary>public class MyTestService : MyTestDemo.MyTestDemoBase{    public override async Task<MultipleRespone> MultipleParam(MultipleRequestPara request, ServerCallContext context)    {return await Task.FromResult(new MultipleRespone{    Success = true,});    }    public override async Task<SingeRespone> NoParam(Empty request, ServerCallContext context)    {       TestEntity t = new TestEntity();       t.Id = 1;       return await Task.FromResult(new SingeRespone { Success = true, entity = t  }); ;    }    public override async Task<CollectionResponePara> CollectionParam(Empty request, ServerCallContext context)    {CollectionResponePara collectionResponePara = new CollectionResponePara();CollectionChildrenRespone1 a = new CollectionChildrenRespone1 { Id = 1 };CollectionChildrenRespone2 b = new CollectionChildrenRespone2 { Name = "jeck" };collectionResponePara.Param1.Add(a);collectionResponePara.Param2.Add(b);return  await  Task.FromResult(collectionResponePara);    }}

    4.創建客戶端,將proto文件拷貝過去調用,添加服務為客戶端模式,然后添加如下代碼

    using (var channel = GrpcChannel.ForAddress("https://localhost:7245")) {     var client =  new MyTestDemo.MyTestDemoClient(channel);     //多參數調用     var reply = client.MultipleParam(new MultipleRequestPara { Id = 123, Name = "sa", IsExists = true });       //無參調用     var singeRespone = client.NoParam(new Google.Protobuf.WellKnownTypes.Empty());     //調用集合     var collectionResponePara = client.CollectionParam(new Google.Protobuf.WellKnownTypes.Empty()); }

    2.gRPC流

    gRPC中支持4種流,分別是:

    1.簡單 RPC(Unary RPC)它的特點是傳入一個請求對象,返回一個請求對象

    2.服務端流式 RPC (Server streaming RPC)客戶端傳入一個請求對象,服務端可以返回多個結果對象,形象的表示就是客戶端傳入一個股票的id,服務端就將股票的信息遠遠不斷地返回

    3.客戶端流式 RPC (Client streaming RPC) 客戶端源源不斷的傳入多個請求對象,服務端返回一個結果對象,形象的表示例如上位機采集實時將采集數據,源源不斷的傳入服務器

    4.雙向流式 RPC (Bi-directional streaming RPC) 結合服務端和客戶端流,傳入多請求,返回多個結果,相當于建立長連接,可以進行相互的操作

    下面我們就主要介紹幾類主要的流的使用以及步驟

    1.服務端流、客戶端流、雙向流

    服務端流主要的特征就是服務端會源源不斷的響應數據到客戶端

    1.首先還是創建protobuf文件,聲明一個服務端流的rpc接口ExcuteServerStream 和一個客戶端流接口ExcuteClientStream

    syntax = "proto3";option csharp_namespace = "GrpcDemo";package streamtest;service StreamTest {  //服務端流定義  rpc ExcuteServerStream(StreamForClientRequest) returns (stream StreamForClientRespones);  //客戶端流定義  rpc ExcuteServerStream(StreamForClientRequest) returns (stream StreamForClientRespones);  //雙向流  rpc ExcuteMutualStream(stream StreamForClientRequest) returns ( stream StreamForClientRespones);}//調用流的請求對象message StreamForClientRequest{    int32 Id=1;}//調用端流的返回對象message StreamForClientRespones{	repeated int32 Number=1;//集合}

    2.重新生成服務引用,然后創建對應的實現接口StreamTestService并重寫生成的服務,然后在啟動程序映射服務接口

    //服務端流接口public override async Task ExcuteServerStream(StreamForClientRequest req,IServerStreamWriter<StreamForClientRespones> resStream,ServerCallContext context){    //list集合作為模擬數據源    var list = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 };    foreach (var item in list)    {Console.WriteLine($"********{item}*******");var ele = new StreamForClientRespones();ele.Number.Add(item);//寫入流中await resStream.WriteAsync(ele);//模擬源源不斷的數據響應await Task.Delay(1000);    }}//客戶端流接口public override async Task<StreamForClientRespones> ExcuteClientStream( IAsyncStreamReader<StreamForClientRequest> requestStream, ServerCallContext context){    StreamForClientRespones intArrayModel = new StreamForClientRespones();    //獲取請求流中的數據    while (await requestStream.MoveNext())    {intArrayModel.Number.Add(requestStream.Current.Id + 1);Console.WriteLine($"ExcuteClientStream Number {requestStream.Current.Id} 獲取到并處理.");Thread.Sleep(100);    }    return intArrayModel;}//雙向流public override async Task ExcuteMutualStream(IAsyncStreamReader<StreamForClientRequest> reqStream,IServerStreamWriter<StreamForClientRespones> resStream,ServerCallContext context){    int i = 0;    //從流中獲取請求    while (await reqStream.MoveNext())    {i++;var ele = new StreamForClientRespones();ele.Number.Add(i);//寫入響應流await resStream.WriteAsync(ele);await Task.Delay(500);    }}

    3.創建客戶端調用,把服務端的protobuf文件拷貝到客戶端,然后生成,啟動調用

    //調用服務端流 using (var channel = GrpcChannel.ForAddress("https://localhost:7245")) {     var client = new StreamTest.StreamTestClient(channel);     //調用服務端流     var reply =  client.ExcuteServerStream(new StreamForClientRequest { Id =1});     //利用線程取消     //CancellationTokenSource cts = new CancellationTokenSource();     //指定在2s后進行取消操作     //cts.CancelAfter(TimeSpan.FromSeconds(2.5));      //var reply = client.ExcuteServerStream(new StreamForClientRequest { Id = 1 }, cancellationToken: cts.Token);     await foreach (var resp in reply.ResponseStream.ReadAllAsync())     { Console.WriteLine(resp.Number[0]);     } } //調用客戶端流 using (var channel = GrpcChannel.ForAddress("https://localhost:7245")) {     var client = new StreamTest.StreamTestClient(channel);     //調用客戶端流接口     var reply = client.ExcuteClientStream();     //模擬源源不斷的數據發送     for (int i = 0; i < 10; i++)     { await reply.RequestStream.WriteAsync(new StreamForClientRequest() { Id = new Random().Next(0, 20) }); await Task.Delay(100);     }     Console.WriteLine("*************發送完畢*******************");     await reply.RequestStream.CompleteAsync();     //接受結果     foreach (var item in reply.ResponseAsync.Result.Number)     { Console.WriteLine($"This is {item} Result");     } }//雙向流using (var channel = GrpcChannel.ForAddress("https://localhost:7245")){    var client = new StreamTest.StreamTestClient(channel);    //調用雙向流接口    var reply = client.ExcuteMutualStream();    //獲取流放入線程    var bathCatRespTask = Task.Run(async () =>    {await foreach (var resp in reply.ResponseStream.ReadAllAsync()){    Console.WriteLine(resp.Number[0]);}    });    //寫入流    for (int i = 0; i < 10; i++)    {await reply.RequestStream.WriteAsync(new StreamForClientRequest() { Id = new Random().Next(0, 20) });await Task.Delay(100);    }    //發送完畢    await reply.RequestStream.CompleteAsync();    //開始接收響應    await bathCatRespTask;}

    2.NetCore Web項目作為客戶端

    1.首先還是先引入proto文件,然后生成客戶端

    2.在web項目中的控制器中,我們就不能直接簡陋的使用 using的方式來連接gRPC服務端了,可以利用內置的依賴注入的模式來完成

    3.下載Grpc.Net.ClientFactory包,然后在`Program將客戶端添加到依賴注入容器

    builder.Services.AddGrpcClient<MyTestDemo.MyTestDemoClient>(option => {    option.Address = new Uri("https://localhost:7245");});

    4.然后在控制器中直接注入,就可以使用

     public class gRPCTestController : ControllerBase {     private readonly MyTestDemoClient _client;     public gRPCTestController(MyTestDemoClient client)     { _client = client;     }     [HttpGet(Name = "Excute")]     public async Task<string> Get()     { var a = await _client.NoParamAsync(new Google.Protobuf.WellKnownTypes.Empty()); var str = a.Success.ToString(); return str;     } }

    5.調用出現如下問題 ,使用dotnet dev-certs https --trust

    3.gRPC AOP攔截

    有時候我們想在gRPC服務執行前后做一些操作,這時候可以使用其Aop攔截,如果你要問攔截器可以做什么,我不太想解釋,繼續往下看,攔截器方法定義在Interceptor類中,服務端和客戶端攔截是一樣的原理,下面列舉一些攔截器:

    名稱特點BlockingUnaryCall攔截阻塞調用AsyncUnaryCall攔截異步調用AsyncServerStreamingCall攔截異步服務端流調用AsyncClientStreamingCall攔截異步客戶端流調用AsyncDuplexStreamingCall攔截異步雙向流調用UnaryServerHandler用于攔截和傳入普通調用的服務器端處理程序ClientStreamingSerHandler用于攔截客戶端流調用的服務器端處理程序ServerStreamingSerHandler用于攔截服務端流調用的服務器端處理程序DuplexStreamingSerHandler用于攔截雙向流調用的服務器端處理程序

    1.聲明一個UnaryServerHandlerInterceptor類型的自定義攔截器,用于攔截和傳入普通調用的服務器端處理程序,然后繼承自Grpc.Core.Interceptors.Interceptor類, 重寫已經定義的方法UnaryServerHandler

    public class UnaryServerHandlerInterceptor : Interceptor{    public override async Task<TResponse> UnaryServerHandler<TRequest, TResponse>(       TRequest request,       ServerCallContext context,       UnaryServerMethod<TRequest, TResponse> continuation)    {Console.WriteLine("執行調用前");var result = await continuation(request, context);Console.WriteLine("執行調用后");// 或向 客戶端附加 一些信息// 也可以 用try catch 做異常日志// 可以從 context中取出 調用方ip,做ip限制// 可以 監控continuation 的 執行時間return result;    } }

    2.然后在注入容器時加入選項

    builder.Services.AddGrpc(option => {     option.EnableDetailedErrors = true;    //加入服務端攔截器選項    option.Interceptors.Add<UnaryServerHandlerInterceptor>();});

    到此這篇關于.NET Core中使用gRPC的文章就介紹到這了,更多相關.NET Core使用gRPC內容請搜索以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持!

    標簽: ASP.NET
    成人在线亚洲_国产日韩视频一区二区三区_久久久国产精品_99国内精品久久久久久久
    国产一区二区三区在线看麻豆| 伊人成人网在线看| 好看不卡的中文字幕| 欧美精品欧美精品系列| 免费的成人av| 色婷婷一区二区三区四区| 亚洲18色成人| 美女91精品| 亚洲欧美电影院| 激情一区二区| 国产精品久久久久久久久久久免费看 | 狠色狠色综合久久| 国产偷国产偷精品高清尤物| av电影在线观看完整版一区二区| 蜜桃伊人久久| 国产亚洲自拍一区| 99精品视频中文字幕| 26uuu国产一区二区三区| 国产成人在线色| 欧美电影免费观看高清完整版在| 国产精品一区二区在线观看网站 | 97精品视频在线观看自产线路二| 亚洲精品在线观看网站| 99久久夜色精品国产网站| 2欧美一区二区三区在线观看视频| 丰满亚洲少妇av| 精品国产欧美一区二区| 午夜视频一区| 国产精品成人一区二区艾草| 亚洲激情午夜| 一区二区免费在线| 亚洲一区二区三区精品动漫| 亚洲va在线va天堂| 欧美专区日韩专区| 国产乱子伦视频一区二区三区| 欧美一级午夜免费电影| jlzzjlzz亚洲女人18| 欧美激情在线一区二区三区| 亚洲国产电影| 亚洲国产精品麻豆| 91久久精品一区二区| 国产一区二区三区黄视频 | 成人免费看的视频| 久久精品一二三| 亚洲午夜伦理| 亚洲在线观看免费视频| 在线日韩av片| 国产成人精品在线看| 久久综合狠狠综合久久激情| 欧美日韩理论| 亚洲在线视频免费观看| 欧美性一二三区| 国产.精品.日韩.另类.中文.在线.播放| 欧美精品一区二区久久婷婷| 亚洲二区免费| 天天影视涩香欲综合网| 欧美男同性恋视频网站| 99久久精品免费精品国产| 亚洲色图在线播放| 色哟哟国产精品免费观看| 国产盗摄一区二区三区| 欧美精彩视频一区二区三区| 国产亚洲福利| 国产一区二区在线观看视频| 久久久久久久久99精品| 国产一区二区三区久久| 寂寞少妇一区二区三区| 久久天天做天天爱综合色| 99视频日韩| 精品一区二区三区香蕉蜜桃| 精品99999| 亚洲视频1区| 狠狠色狠狠色综合| 中文av字幕一区| 色国产综合视频| www.66久久| 亚洲综合色视频| 欧美剧在线免费观看网站| 欧美国产高清| 日本伊人色综合网| 久久五月婷婷丁香社区| 美女网站久久| av电影天堂一区二区在线 | 亚洲欧美一区二区三区久本道91| 久久先锋影音| 99久久精品久久久久久清纯| 性做久久久久久久久| 欧美日韩亚洲高清一区二区| 欧美日韩一区二区视频在线观看| 亚洲高清免费一级二级三级| 欧美一区二区三区播放老司机| 一区二区在线不卡| 久久99久久精品| 国产精品久久久久久久久久免费看| 在线观看欧美日本| 欧美午夜久久| 久久精品国产精品青草| 久久久久久久综合| 亚洲欧美久久| zzijzzij亚洲日本少妇熟睡| 五月婷婷综合激情| 国产午夜亚洲精品理论片色戒 | 成人h动漫精品| 午夜欧美视频在线观看| 久久蜜桃一区二区| 在线看日本不卡| 激情欧美一区| 国产成人av影院| 亚洲精品国产a久久久久久| 日韩午夜av电影| 久久亚洲风情| 红桃视频国产一区| 国产不卡视频一区| 日韩成人av影视| 亚洲人成精品久久久久| 欧美成人午夜电影| 久久久av水蜜桃| 国产综合视频| 国v精品久久久网| 日韩电影免费在线看| 中文字幕亚洲不卡| 欧美www视频| 欧美在线免费播放| 日韩亚洲不卡在线| 91美女精品福利| 国产一区二区三区精品视频| 亚洲成人免费看| 国产精品美女久久久久av爽李琼| 日韩视频免费直播| 快she精品国产999| 亚洲三级视频| 欧美日韩国产精品一卡| 国产成人av资源| 九色综合国产一区二区三区| 亚洲成在线观看| 亚洲欧美日韩小说| 国产欧美一区二区精品久导航| 在线电影一区二区三区| 久热综合在线亚洲精品| 一本久道综合久久精品| 欧美午夜精彩| 97精品超碰一区二区三区| 国产精品综合网| 久久成人免费网| 亚洲v中文字幕| 一区二区三国产精华液| 中文字幕日韩一区| 国产日韩精品一区二区浪潮av| 日韩视频一区二区在线观看| 欧美日韩精品免费观看视频 | 欧美高清日韩| av一二三不卡影片| 岛国一区二区三区| 国产精品一品二品| 久久国内精品自在自线400部| 亚洲国产精品嫩草影院| 亚洲日本欧美天堂| 亚洲欧洲成人自拍| 国产精品嫩草99a| 国产情人综合久久777777| 久久影视一区二区| 久久夜色精品国产欧美乱极品| 91麻豆精品国产91久久久久久久久| 欧美在线你懂得| 在线影视一区二区三区| 久久精品人人| 老司机一区二区三区 | 精品久久国产97色综合| 91精品国产91久久久久久最新毛片| 欧美中文字幕不卡| 91福利在线播放| 在线视频国内一区二区| 日本韩国精品在线| 色噜噜狠狠色综合中国| 在线视频你懂得一区二区三区| 欧美综合亚洲图片综合区| 欧美天堂一区二区三区| 欧美少妇一区二区| 欧美人与z0zoxxxx视频| 欧美男男青年gay1069videost | 欧美一区二区三区在线观看视频| 555www色欧美视频| 日韩三级精品电影久久久| 精品三级av在线| 精品久久久久久久人人人人传媒| 26uuu精品一区二区| 国产三级精品在线| 一区在线中文字幕| 亚洲老司机在线| 亚洲www啪成人一区二区麻豆| 日韩制服丝袜av| 精品在线观看免费| 国产老女人精品毛片久久| 伊人久久婷婷色综合98网| 国产精品资源网站| 国产精品99久久久久久宅男| 国内精品自线一区二区三区视频| 国产美女一区二区| 粉嫩一区二区三区在线看| 99精品在线免费|