|
| 1 | +#### Client端配置使用 |
| 2 | +首先新建任意形式的.net core宿主,为了简单我使用的是Console程序,引入DotNetCoreRpc.Client包和DependencyInjection相关包 |
| 3 | +``` |
| 4 | +<PackageReference Include="DotNetCoreRpc.Client" Version="1.1.3" /> |
| 5 | +``` |
| 6 | +引入自己的服务接口包我这里是Test.IService,只需要引入interface层即可,写入如下测试代码,具体代码可参阅demo,由于DotNetCoreRpc通信是基于HttpClientFactory的,所以需要注册HttpClientFactory |
| 7 | +```cs |
| 8 | +class Program |
| 9 | +{ |
| 10 | + //TestServer服务名称 |
| 11 | + const string TestServerName = "TestServer"; |
| 12 | + |
| 13 | + static async Task Main(string[] args) |
| 14 | + { |
| 15 | + var builder = new ConfigurationBuilder() |
| 16 | + .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true); |
| 17 | + var configuration = builder.Build(); |
| 18 | + |
| 19 | + IServiceCollection services = new ServiceCollection(); |
| 20 | + services.AddLogging().AddDotNetCoreRpcClient() |
| 21 | + //单机版Httpclient配置 |
| 22 | + .AddHttpClient(TestServerName, client => { client.BaseAddress = new Uri("http://localhost:34047/Test.Server6"); }); |
| 23 | + //基于Nacos注册中心 |
| 24 | + //.AddNacosV2Naming(configuration) |
| 25 | + //.AddScoped<NacosDiscoveryDelegatingHandler>() |
| 26 | + //.AddHttpClient(TestServerName, client => |
| 27 | + //{ |
| 28 | + // client.BaseAddress = new Uri($"http://{TestServerName}/Test.Server6"); |
| 29 | + //}).AddHttpMessageHandler<NacosDiscoveryDelegatingHandler>(); |
| 30 | +
|
| 31 | + IServiceProvider serviceProvider = services.BuildServiceProvider(); |
| 32 | + RpcClient rpcClient = serviceProvider.GetRequiredService<RpcClient>(); |
| 33 | + IPersonService personService = rpcClient.CreateClient<IPersonService>(TestServerName); |
| 34 | + |
| 35 | + PersonModel person = new PersonModel |
| 36 | + { |
| 37 | + Id = 1, |
| 38 | + Name = "softlgl", |
| 39 | + IdCardNo = 5555555, |
| 40 | + BirthDay = DateTime.Now, |
| 41 | + HasMoney = false |
| 42 | + }; |
| 43 | + bool add = await personService.Add(person); |
| 44 | + Console.WriteLine($"添加Person1:{add}"); |
| 45 | + person = personService.Get(1); |
| 46 | + Console.WriteLine($"获取Person,id=1,person=[{person.ToJson()}]"); |
| 47 | + person = new PersonModel |
| 48 | + { |
| 49 | + Id = 2, |
| 50 | + Name = "yi念之间", |
| 51 | + IdCardNo = 666888, |
| 52 | + BirthDay = DateTime.Now, |
| 53 | + HasMoney = false |
| 54 | + }; |
| 55 | + add = await personService.Add(person); |
| 56 | + Console.WriteLine($"添加Person2:{add}"); |
| 57 | + var persons = await personService.GetPersons(); |
| 58 | + Console.WriteLine($"获取Persons,persons=[{persons.ToJson()}]"); |
| 59 | + await personService.Edit(1); |
| 60 | + Console.WriteLine($"修改Person,id=1完成"); |
| 61 | + personService.Delete(1); |
| 62 | + Console.WriteLine($"删除Person,id=1完成"); |
| 63 | + persons = await personService.GetPersons(); |
| 64 | + Console.WriteLine($"最后获取Persons,persons=[{persons.ToJson()}]"); |
| 65 | + |
| 66 | + IProductService productService = rpcClient.CreateClient<IProductService>(TestServerName); |
| 67 | + ProductDto product = new ProductDto |
| 68 | + { |
| 69 | + Id = 1000, |
| 70 | + Name="抗原", |
| 71 | + Price = 158.22M |
| 72 | + }; |
| 73 | + int productAddResult = await productService.Add(product); |
| 74 | + Console.WriteLine($"添加Product1:{productAddResult==1}"); |
| 75 | + product = productService.Get(1000); |
| 76 | + Console.WriteLine($"获取添加Product1,id=1000,person=[{product.ToJson()}]"); |
| 77 | + product = new ProductDto |
| 78 | + { |
| 79 | + Id = 2000, |
| 80 | + Name = "N95口罩", |
| 81 | + Price = 35.5M |
| 82 | + }; |
| 83 | + productAddResult = await productService.Add(product); |
| 84 | + Console.WriteLine($"添加Product2:{productAddResult == 1}"); |
| 85 | + product = productService.Get(2000); |
| 86 | + Console.WriteLine($"获取添加Product2,id=2000,person=[{product.ToJson()}]"); |
| 87 | + var products = await productService.GetProducts(); |
| 88 | + Console.WriteLine($"products=[{products.ToJson()}]"); |
| 89 | + Task editTask = productService.Edit(1); |
| 90 | + await editTask; |
| 91 | + Console.WriteLine($"修改Product,id=1完成"); |
| 92 | + |
| 93 | + Console.ReadLine(); |
| 94 | + } |
| 95 | +} |
| 96 | +``` |
| 97 | +#### Server端配置使用 |
| 98 | + |
| 99 | +新建一个最简单的Asp.net Core项目,我这里的Demo是新建的Asp.net Core的空项目,引入DotNetCoreRpc.Server包 |
| 100 | +``` |
| 101 | +<PackageReference Include="DotNetCoreRpc.Server" Version="1.1.3" /> |
| 102 | +``` |
| 103 | +然后添加注入和相关中间件 |
| 104 | +```cs |
| 105 | +public class Startup |
| 106 | +{ |
| 107 | + public void ConfigureServices(IServiceCollection services) |
| 108 | + { |
| 109 | + services.AddSingleton<IPersonDal, PersonDal>() |
| 110 | + .AddSingleton<IPersonService, PersonService>() |
| 111 | + .AddSingleton<IProductDal, ProductDal>() |
| 112 | + .AddSingleton<IProductService, ProductService>() |
| 113 | + .AddSingleton(new RedisConfig { Address="127.0.0.1:6379",db=10 }) |
| 114 | + .AddSingleton(new ElasticSearchConfig { Address = "127.0.0.1:9200" }) |
| 115 | + //*注册DotNetCoreRpcServer |
| 116 | + .AddDotNetCoreRpcServer(options => { |
| 117 | + //*确保以下添加的服务已经被注册到DI容器 |
| 118 | + |
| 119 | + //添加作为服务的接口 |
| 120 | + //options.AddService<IPersonService>(); |
| 121 | + |
| 122 | + //或添加作为服务的接口以xxx为结尾的接口 |
| 123 | + //options.AddService("*Service"); |
| 124 | + |
| 125 | + //或添加具体名称为xxx的接口 |
| 126 | + //options.AddService("IPersonService"); |
| 127 | + //或具体命名空间下的接口 |
| 128 | + options.AddNameSpace("Test.IService"); |
| 129 | + |
| 130 | + //添加全局过滤器 |
| 131 | + options.AddFilter<CacheFilter>(); |
| 132 | + }); |
| 133 | + } |
| 134 | + |
| 135 | + public void Configure(IApplicationBuilder app, IWebHostEnvironment env) |
| 136 | + { |
| 137 | + //通过中间件的方式引入 |
| 138 | + //app.UseDotNetCoreRpc(); |
| 139 | + app.UseRouting(); |
| 140 | + app.UseEndpoints(endpoint => { |
| 141 | + endpoint.Map("/", async context=>await context.Response.WriteAsync("server start!")); |
| 142 | + //通过endpoint的方式引入 |
| 143 | + endpoint.MapDotNetCoreRpc(); |
| 144 | + //endpoint.MapDotNetCoreRpc("/Test.Server6"); |
| 145 | + }); |
| 146 | + } |
| 147 | +} |
| 148 | +``` |
| 149 | +如果是ASP.NET Core 6的Minimal Api则使用以下方式 |
| 150 | +```cs |
| 151 | +var builder = WebApplication.CreateBuilder(args); |
| 152 | + |
| 153 | +builder.Services.AddSingleton<IPersonDal, PersonDal>() |
| 154 | + .AddSingleton<IPersonService, PersonService>() |
| 155 | + .AddSingleton<IProductDal, ProductDal>() |
| 156 | + .AddSingleton<IProductService, ProductService>() |
| 157 | + .AddSingleton(new RedisConfig { Address = "127.0.0.1:6379", db = 10 }) |
| 158 | + .AddSingleton(new ElasticSearchConfig { Address = "127.0.0.1:9200" }) |
| 159 | + .AddDotNetCoreRpcServer(options => { |
| 160 | + //options.AddService<IPersonService>(); |
| 161 | + //options.AddService("*Service"); |
| 162 | + //options.AddService("IPersonService"); |
| 163 | + options.AddNameSpace("Test.IService"); |
| 164 | + options.AddFilter<CacheFilter>(); |
| 165 | + }); |
| 166 | + |
| 167 | +app.UseDotNetCoreRpc(); |
| 168 | +//app.UseDotNetCoreRpc("/Test.Server6"); |
| 169 | +app.MapGet("/", () => "Hello World!"); |
| 170 | + |
| 171 | +app.Run(); |
| 172 | +``` |
| 173 | +过滤器的使用方式,可添加到类上或者方法上或者全局注册,优先级 方法>类>全局注册,RpcFilterAttribute是基于管道模式执行的,可支持注册多个Filter,支持属性注入。 |
| 174 | +```cs |
| 175 | +public class CacheFilter : RpcFilterAttribute |
| 176 | +{ |
| 177 | + private readonly ElasticSearchConfig _elasticSearchConfig; |
| 178 | + |
| 179 | + [FromServices] |
| 180 | + private RedisConfig RedisConfig { get; set; } |
| 181 | + |
| 182 | + [FromServices] |
| 183 | + private ILogger<CacheFilter> Logger { get; set; } |
| 184 | + |
| 185 | + public CacheFilter(ElasticSearchConfig elasticSearchConfig) |
| 186 | + { |
| 187 | + _elasticSearchConfig = elasticSearchConfig; |
| 188 | + } |
| 189 | + public override async Task InvokeAsync(RpcContext context, RpcRequestDelegate next) |
| 190 | + { |
| 191 | + Logger.LogInformation($"CacheFilter begin,Parameters={context.Parameters}"); |
| 192 | + await next(context); |
| 193 | + Logger.LogInformation($"CacheFilter end,ReturnValue={context.ReturnValue.ToJson()}"); |
| 194 | + } |
| 195 | +} |
| 196 | +``` |
0 commit comments