之前通過自己寫動態代理和用現成的動態代理庫等實現過RPC功能,今天,就寫一下如何直接引用GRPC的庫來實現業務邏輯。
gRPC的介紹,之前我也說了這個g的含義太多,也包含谷歌的意思了。
可以看這個gRPC的文檔介紹 : https://grpc.io/docs/what-is-grpc/
MagicOnion這個庫用它是因為它內部使用了 MessagePack-CSharp 序列化方式,這種方式效果要比谷歌的protobuf 效果還要好,更重要的是在Net這個平臺下來看的。
MagicOnion 是用于 .NET 平臺的現代 RPC 框架,它提供雙向實時通信(例如SignalR和Socket.io)以及 RPC 機制(例如 WCF 和基于 Web 的 API)。
該框架基于gRPC,它是一種用于 HTTP/2 的快速且緊湊的二進制網絡傳輸。但是,與普通 gRPC 不同,它將 C# 接口視為協議模式,從而無需.proto(Protocol Buffers IDL)即可在 C# 項目之間實現無縫代碼共享。

接口是模式并提供 API 服務,就像普通的 C# 代碼一樣

其中 MagicOnion開源地址:https://github.com/Cysharp/MagicOnion
實現gRPC業務
我這邊結構如下:

客戶端,服務端,以及共享接口,三部分組成。
主要引用的Nuget包為:
MagicOnion
MagicOnion.Server
MagicOnion.Client
接口定義
接口定義,是我直接拿之前做的demo的樣子直接搞的。也方便。
IDemo.cs
public?interface?IDemo?:?IService<IDemo>
{UnaryResult<string>?Say1(string?msg);UnaryResult<int>?Say2(string?a,?int?b,?List<string>?c,?Kind?kind);UnaryResult<Kind>?Say3(int?b,?List<string>?c,?Kind?kind);???
}
public?enum?Kind
{a,b
}
注
用了這個服務才發現,它不能像我之前自己實現的那樣,還能實現Viod返回類型和重載函數名等操作。
所以,它只能用于服務類的通訊,不能像函數那樣用,另外 UnaryResult?返回類型是必須的,這是需要注意的。
服務端
我這邊是直接新建了一個asp.net core web api,注釋新增的部分,就是我新增的代碼。
public?static?void?Main(string[]?args)
{var?builder?=?WebApplication.CreateBuilder(args);//?Add?services?to?the?container.builder.Services.AddControllers();//?Learn?more?about?configuring?Swagger/OpenAPI?at?https://aka.ms/aspnetcore/swashbucklebuilder.Services.AddEndpointsApiExplorer();builder.Services.AddSwaggerGen();//新增//增加Grpcbuilder.Services.AddGrpc();builder.Services.AddMagicOnion();var?app?=?builder.Build();//新增app.UseRouting();//?Configure?the?HTTP?request?pipeline.if?(app.Environment.IsDevelopment()){app.UseSwagger();app.UseSwaggerUI();}app.UseAuthorization();app.MapControllers();//新增app.UseEndpoints(endpoints?=>{endpoints.MapMagicOnionService();endpoints.MapGet("/",?async?context?=>{context.Response.ContentType?=?"text/plain;?charset=utf-8";?await?context.Response.WriteAsync("Grpc服務端已經創立,等待Grpc客戶端連接!");});});app.Run();
}
Demo接口服務端實現
public?class?Demo?:?ServiceBase<IDemo>,?IDemo
{public?async?UnaryResult<string>?Say1(string?msg){return?msg;}public?async?UnaryResult<int>?Say2(string?a,?int?b,?List<string>?c,?Kind?kind){return?b;}public?async?UnaryResult<Kind>?Say3(int?b,?List<string>?c,?Kind?kind){return?kind;}
}
注
實現接口的同時也要繼承eBase類,要不然,總有一些接口的方法未實現。
客戶端
客戶端就簡單許多了
static?async?Task?Main(string[]?args)
{Console.Title?=?"GrpcDemo?by?藍創精英團隊";var?channel?=?GrpcChannel.ForAddress("https://localhost:5001");var?demo?=?MagicOnionClient.Create<IDemo>(channel);Console.WriteLine(await?demo.Say1("123"));Console.WriteLine(await?demo.Say2("demo",?6,?new?List<string>()?{?"6"?},?Kind.b));Console.WriteLine(await?demo.Say3(1,?new?List<string>(),?Kind.a));Console.WriteLine("不錯,完成了任務!");Console.ReadLine();
}
效果
先運行服務端:
游覽器打開地址 : https://localhost:5001/
就可以看到下面的內容,說明服務成功啟動!

然后,再運行客戶端
結果如下:

用別人的庫,確實方便許多。
總結
至此,RPC系列已經完結了,撒花,歐耶!
看著簡單,搞著不知不覺已經夜深人靜了,山中無歲月,世上已千年啊。
代碼地址
https://github.com/kesshei/GrpcDemo.git
https://gitee.com/kesshei/GrpcDemo.git
閱
一鍵三連呦!,感謝大佬的支持,您的支持就是我的動力!