基于.NetCore的RPC框架DotNetCoreRpc都是怎样的

80次阅读
没有评论

共计 4703 个字符,预计需要花费 12 分钟才能阅读完成。

今天给大家介绍一下基于.NetCore 的 RPC 框架 DotNetCoreRpc 都是怎样的。文章的内容丸趣 TV 小编觉得不错,现在给大家分享一下,觉得有需要的朋友可以了解一下,希望对大家有所帮助,下面跟着丸趣 TV 小编的思路一起来阅读吧。

前言

  一直以来对内部服务间使用 RPC 的方式调用都比较赞同, 因为内部间没有这么多限制,最简单明了的方式就是最合适的方式。个人比较喜欢类似 Dubbo 的那种使用方式,采用和本地方法相同的方式,把接口层独立出来作为服务契约,为服务端提供服务,客户端也通过此契约调用服务。.Net 平台上类似 Dubbo 这种相对比较完善的 RPC 框架还是比较少的,GRPC 确实是一款非常优秀的 RPC 框架,能跨语言调用,但是每次还得编写 proto 文件,个人感觉还是比较麻烦的。如今服务拆分,微服务架构比较盛行的潮流下,一个简单实用的 RPC 框架确实可以提升很多开发效率。

简介

  随着.Net Core 逐渐成熟稳定,为我一直以来想实现的这个目标提供了便利的方式。于是利用闲暇时间本人手写了一套基于 Asp.Net Core 的 RPC 框架,算是实现了一个自己的小目标。大致的实现方式,Server 端依赖 Asp.Net Core,采用的是中间件的方式拦截处理请求比较方便。Client 端可以是任何可承载.Net Core 的宿主程序。通信方式是 HTTP 协议,使用的是 HttpClientFactory。至于为什么使用 HttpClientFactory,因为 HttpClientFactory 可以更轻松的实现服务发现,而且可以很好的集成 Polly,很方便的实现,超时重试,熔断降级这些,给开发过程中提供了很多便利。由于本人能力有限,基于这些便利,站在巨人的肩膀上,简单的实现了一个 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 连接, 建完这些之后项目结构如下:

Client 端配置 #

Client 端引入 DotNetCoreRpc.Client 包,并引入自定义的契约接口层

PackageReference Include= DotNetCoreRpc.Client

然后可以愉快的编码了,大致编码如下

class Program
 static void Main(string[] args)
 { IServiceCollection services = new ServiceCollection();
 //* 注册 DotNetCoreRpcClient 核心服务
 services.AddDotNetCoreRpcClient()
 //* 通信是基于 HTTP 的, 内部使用的 HttpClientFactory, 自行注册即可
 .AddHttpClient(WebDemo , client =  { client.BaseAddress = new Uri( http://localhost:13285/  });
 IServiceProvider serviceProvider = services.BuildServiceProvider();
 //* 获取 RpcClient 使用这个类创建具体服务代理对象
 RpcClient rpcClient = serviceProvider.GetRequiredService RpcClient 
 //IPersonService 是我引入的服务包 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($ 添加结果 =[{addFlag}] 
 var person = personService.Get(personDto.Id);
 Console.WriteLine($ 获取 person 结果 =[{person.ToJson()}] 
 var persons = personService.GetAll();
 Console.WriteLine($ 获取 persons 结果 =[{persons.ToList().ToJson()}] 
 personService.Delete(person.Id);
 Console.WriteLine($ 删除完成 
 Console.ReadLine();
 }
}

到这里 Client 端的代码就编写完成了

Server 端配置 #

Client 端引入 DotNetCoreRpc.Client 包,并引入自定义的契约接口层

PackageReference Include= DotNetCoreRpc.Server  Version= 1.0.2  /

然后编写契约接口实现类,比如我的叫 PersonService

// 实现契约接口 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}], >

以上代码基本上完成了对服务端业务代码的操作, 接下来我们来看如何在 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 =  {
 //* 确保添加的契约服务接口事先已经被注册到 DI 容器中
 // 添加契约接口
 //options.AddService IPersonService 
 // 或添加契约接口名称以 xxx 为结尾的
 //options.AddService( *Service 
 // 或添加具体名称为 xxx 的契约接口
 //options.AddService( IPersonService 
 // 或扫描具体命名空间下的契约接口
 options.AddNameSpace( IRpcService 
 // 可以添加全局过滤器, 实现方式和 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 都是怎样的相关的内容可以搜索丸趣 TV 之前的文章或者浏览下面的文章进行学习哈!相信丸趣 TV 小编会给大家增添更多知识, 希望大家能够支持一下丸趣 TV!

正文完
 
丸趣
版权声明:本站原创文章,由 丸趣 2023-08-04发表,共计4703字。
转载说明:除特殊说明外本站除技术相关以外文章皆由网络搜集发布,转载请注明出处。
评论(没有评论)