今天給大家介紹一下基于.NetCore的RPC框架DotNetCoreRpc都是怎樣的。文章的內(nèi)容小編覺得不錯,現(xiàn)在給大家分享一下,覺得有需要的朋友可以了解一下,希望對大家有所幫助,下面跟著小編的思路一起來閱讀吧。
成都創(chuàng)新互聯(lián)公司自成立以來,一直致力于為企業(yè)提供從網(wǎng)站策劃、網(wǎng)站設(shè)計、成都網(wǎng)站設(shè)計、網(wǎng)站建設(shè)、電子商務(wù)、網(wǎng)站推廣、網(wǎng)站優(yōu)化到為企業(yè)提供個性化軟件開發(fā)等基于互聯(lián)網(wǎng)的全面整合營銷服務(wù)。公司擁有豐富的網(wǎng)站建設(shè)和互聯(lián)網(wǎng)應(yīng)用系統(tǒng)開發(fā)管理經(jīng)驗、成熟的應(yīng)用系統(tǒng)解決方案、優(yōu)秀的網(wǎng)站開發(fā)工程師團隊及專業(yè)的網(wǎng)站設(shè)計師團隊。
一直以來對內(nèi)部服務(wù)間使用RPC的方式調(diào)用都比較贊同,因為內(nèi)部間沒有這么多限制,最簡單明了的方式就是最合適的方式。個人比較喜歡類似Dubbo的那種使用方式,采用和本地方法相同的方式,把接口層獨立出來作為服務(wù)契約,為服務(wù)端提供服務(wù),客戶端也通過此契約調(diào)用服務(wù)。.Net平臺上類似Dubbo這種相對比較完善的RPC框架還是比較少的,GRPC確實是一款非常優(yōu)秀的RPC框架,能跨語言調(diào)用,但是每次還得編寫proto文件,個人感覺還是比較麻煩的。如今服務(wù)拆分,微服務(wù)架構(gòu)比較盛行的潮流下,一個簡單實用的RPC框架確實可以提升很多開發(fā)效率。
隨著.Net Core逐漸成熟穩(wěn)定,為我一直以來想實現(xiàn)的這個目標提供了便利的方式。于是利用閑暇時間本人手寫了一套基于Asp.Net Core的RPC框架,算是實現(xiàn)了一個自己的小目標。大致的實現(xiàn)方式,Server端依賴Asp.Net Core,采用的是中間件的方式攔截處理請求比較方便。Client端可以是任何可承載.Net Core的宿主程序。通信方式是HTTP協(xié)議,使用的是HttpClientFactory。至于為什么使用HttpClientFactory,因為HttpClientFactory可以更輕松的實現(xiàn)服務(wù)發(fā)現(xiàn),而且可以很好的集成Polly,很方便的實現(xiàn),超時重試,熔斷降級這些,給開發(fā)過程中提供了很多便利。由于本人能力有限,基于這些便利,站在巨人的肩膀上,簡單的實現(xiàn)了一個RPC框架,項目托管在GitHub上https://github.com/softlgl/DotNetCoreRpc有興趣的可以自行查閱。
Visual Studio 2019
.Net Standard 2.1
Asp.Net Core 3.1.x
打開Visual Studio先新建一個RPC契約接口層,這里我起的名字叫IRpcService。然后新建一個Client層(可以是任何可承載.Net Core的宿主程序)叫ClientDemo,然后建立一個Server層(必須是Asp.Net Core項目)叫WebDemo,文末附本文Demo連接,建完這些之后項目結(jié)構(gòu)如下:
Client端引入DotNetCoreRpc.Client包,并引入自定義的契約接口層
<PackageReference Include="DotNetCoreRpc.Client">
然后可以愉快的編碼了,大致編碼如下
class Program { static void Main(string[] args) { IServiceCollection services = new ServiceCollection(); //*注冊DotNetCoreRpcClient核心服務(wù) services.AddDotNetCoreRpcClient() //*通信是基于HTTP的,內(nèi)部使用的HttpClientFactory,自行注冊即可 .AddHttpClient("WebDemo", client => { client.BaseAddress = new Uri("http://localhost:13285/"); }); IServiceProvider serviceProvider = services.BuildServiceProvider(); //*獲取RpcClient使用這個類創(chuàng)建具體服務(wù)代理對象 RpcClient rpcClient = serviceProvider.GetRequiredService<RpcClient>(); //IPersonService是我引入的服務(wù)包interface,需要提供ServiceName,即AddHttpClient的名稱 IPersonService personService = rpcClient.CreateClient<IPersonService>("WebDemo"); PersonDto personDto = new PersonDto { Id = 1, Name = "yi念之間", Address = "中國", BirthDay = new DateTime(2000,12,12), IsMarried = true, Tel = 88888888888 }; bool addFlag = personService.Add(personDto); Console.WriteLine($"添加結(jié)果=[{addFlag}]"); var person = personService.Get(personDto.Id); Console.WriteLine($"獲取person結(jié)果=[{person.ToJson()}]"); var persons = personService.GetAll(); Console.WriteLine($"獲取persons結(jié)果=[{persons.ToList().ToJson()}]"); personService.Delete(person.Id); Console.WriteLine($"刪除完成"); Console.ReadLine(); } }
到這里Client端的代碼就編寫完成了
Client端引入DotNetCoreRpc.Client包,并引入自定義的契約接口層
<PackageReference Include="DotNetCoreRpc.Server" Version="1.0.2" />
然后編寫契約接口實現(xiàn)類,比如我的叫PersonService
//實現(xiàn)契約接口IPersonService public class PersonService:IPersonService { private readonly ConcurrentDictionary<int, PersonDto> persons = new ConcurrentDictionary<int, PersonDto>(); public bool Add(PersonDto person) { return persons.TryAdd(person.Id, person); } public void Delete(int id) { persons.Remove(id,out PersonDto person); } //自定義Filter [CacheFilter(CacheTime = 500)] public PersonDto Get(int id) { return persons.GetValueOrDefault(id); } //自定義Filter [CacheFilter(CacheTime = 300)] public IEnumerable<PersonDto> GetAll() { foreach (var item in persons) { yield return item.Value; } } }
通過上面的代碼可以看出,我自定義了Filter,這里的Filter并非Asp.Net Core框架定義的Filter,而是DotNetCoreRpc框架定義的Filter,自定義Filter的方式如下
//*要繼承自抽象類RpcFilterAttribute public class CacheFilterAttribute: RpcFilterAttribute { public int CacheTime { get; set; } //*支持屬性注入,可以是public或者private //*這里的FromServices并非Asp.Net Core命名空間下的,而是來自DotNetCoreRpc.Core命名空間 [FromServices] private redisConfigOptions RedisConfig { get; set; } [FromServices] public ILogger<CacheFilterAttribute> Logger { get; set; } public override async Task InvokeAsync(RpcContext context, RpcRequestDelegate next) { Logger.LogInformation($"CacheFilterAttribute Begin,CacheTime=[{CacheTime}],Class=[{context.TargetType.FullName}],Method=[{context.Method.Name}],Params=[{JsonConvert.SerializeObject(context.Parameters)}]"); await next(context); Logger.LogInformation($"CacheFilterAttribute End,ReturnValue=[{JsonConvert.SerializeObject(context.ReturnValue)}]"); } }
以上代碼基本上完成了對服務(wù)端業(yè)務(wù)代碼的操作,接下來我們來看如何在Asp.Net Core中配置使用DotNetCoreRpc。打開Startup,配置如下代碼既可
public class Startup { public void ConfigureServices(IServiceCollection services) { services.AddSingleton<IPersonService, PersonService>() .AddSingleton(new RedisConfigOptions { Address = "127.0.0.1:6379", Db = 10 }) //*注冊DotNetCoreRpcServer .AddDotNetCoreRpcServer(options => { //*確保添加的契約服務(wù)接口事先已經(jīng)被注冊到DI容器中 //添加契約接口 //options.AddService<IPersonService>(); //或添加契約接口名稱以xxx為結(jié)尾的 //options.AddService("*Service"); //或添加具體名稱為xxx的契約接口 //options.AddService("IPersonService"); //或掃描具體命名空間下的契約接口 options.AddNameSpace("IRpcService"); //可以添加全局過濾器,實現(xiàn)方式和CacheFilterAttribute一致 options.AddFilter<LoggerFilterAttribute>(); }); } public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { //這一堆可以不要+1 if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } //添加DotNetCoreRpc中間件既可 app.UseDotNetCoreRpc(); //這一堆可以不要+2 app.UseRouting(); //這一堆可以不要+3 app.UseEndpoints(endpoints => { endpoints.MapGet("/", async context => { await context.Response.WriteAsync("Server Start!"); }); }); } }
DotNetCoreRpc都是怎樣的相關(guān)的內(nèi)容可以搜索創(chuàng)新互聯(lián)之前的文章或者瀏覽下面的文章進行學(xué)習(xí)哈!相信小編會給大家增添更多知識,希望大家能夠支持一下創(chuàng)新互聯(lián)!
網(wǎng)站標題:基于.NetCore的RPC框架DotNetCoreRpc都是怎樣的
網(wǎng)站路徑:http://aaarwkj.com/article4/gihioe.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站排名、建站公司、營銷型網(wǎng)站建設(shè)、網(wǎng)站維護、外貿(mào)網(wǎng)站建設(shè)、企業(yè)建站
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)