一个能够在Asp.Net和Asp.NetCore之间能够互相通讯的Rpc
Posted yjq_叶
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一个能够在Asp.Net和Asp.NetCore之间能够互相通讯的Rpc相关的知识,希望对你有一定的参考价值。
一、特性
1、跨平台
2、提供负载均衡算法
3、支持ZK服务协调
4、提供了JSON、BinarySerializer、还有自定义的序列化方式
5、客户端提供Socket连接池,以便于快速交互,防止类似大文件上传时会阻塞
6、支持异步方法
7、支持.net与.netcore之间通信
8、支持采用MongoDb收集请求信息(采用双缓冲队列,极限的不影响传输速度)
9、提供请求日志监控后台(还未全部完善)
二、项目结构
编译器采用vs2017.
NRpcItem 是Framework下的NRpc源代码。NetCoreRpcItem是.NetCore下的源代码。NRpcSerializer是自己写的一个序列化方法,速度和json序列化对比稍慢一点,但是速度可以接收。
值得注意的是NRpcItem 里面采用Autofac来作为IOC容器,服务端的代码都必须要基于Autofac来实现依赖注入。
NRpc.AdminManage是日志监控后台,目前只有.netCore版本。
三、自定义序列化方法性能测试
虽然在执行速度上比json稍慢,但是支持对byte[]类型的序列化,而且客户端不需要任何的标记,方便使用。实现过程中参考csharp-hessian的序列化实现方式,支持跨平台。
四、如何使用Rpc
1、服务端:
a、参考NetCoreRpc.Application项目,先定义好IStudentApplication以及他的实现类StudentApplication
b、参考NetCoreRpc.ServerTest项目中Program,先绑定好依赖注入信息,如果要使用zk,则加上.UseZK();扩展方法,不然不采用ZK的服务发现
private static IServiceProvider BuildDi() { IServiceCollection services = new ServiceCollection(); services.AddSingleton<ILoggerFactory, LoggerFactory>(); services.AddSingleton(typeof(ILogger<>), typeof(Logger<>)); services.AddSingleton<IStudentApplication, StudentApplication>(); var str = Configuration.GetValue<string>("MongoDB:Str"); var dbName = Configuration.GetValue<string>("MongoDB:DatabaseName"); services.UseRpc() .UseMongoDBMonitor(() => { return new MonogoDbConfig(str, dbName); });//.UseZK(); var serviceProvider = services.BuildServiceProvider(); var loggerFactory = serviceProvider.GetRequiredService<ILoggerFactory>(); loggerFactory.AddNLog(new NLogProviderOptions { CaptureMessageTemplates = true, CaptureMessageProperties = true }); loggerFactory.ConfigureNLog("NLog.config"); return serviceProvider; }
c、配置文件信息,配置ZK和MongoDb链接配置信息
{ "NetCoreRpc": { "Zookeeper": { "Connection": "192.168.100.34:2181", "ParentName": "/NetCoreRpc/ClientTest" } }, "MongoDB": { "Str": "mongodb://root:root@192.168.100.125:27017", "DatabaseName": "Rpc_Monitor" } }
d、开启监听
private static void Main(string[] args) { Console.WriteLine("请输入监听端口:"); var strPort = Console.ReadLine(); var builder = new ConfigurationBuilder() .SetBasePath(Path.Combine(AppContext.BaseDirectory)).AddJsonFile("NetCoreRpc.json", optional: true); Configuration = builder.Build(); var servicesProvider = BuildDi(); DependencyManage.SetServiceProvider(servicesProvider, Configuration); NRpcServer nrpcServer = new NRpcServer(int.Parse(strPort)); nrpcServer.Start("NetCoreRpc.Application"); Console.WriteLine("Welcome to use NetCoreRpc!"); Console.WriteLine("Input exit to exit"); var str = Console.ReadLine(); while (!string.Equals(str, "exit", StringComparison.OrdinalIgnoreCase)) { str = Console.ReadLine(); } nrpcServer.ShutDown(); }
2、客户端如何调用
a、参考NetCoreRpc.ClientTest项目先配置一些基础的依赖信息
private static IServiceProvider BuildDi() { IServiceCollection services = new ServiceCollection(); services.AddOptions(); services.Configure<RpcConfig>(Configuration.GetSection("NetCoreRpc")); services.AddSingleton<ILoggerFactory, LoggerFactory>(); services.AddSingleton(typeof(ILogger<>), typeof(Logger<>)); services.UseRpc().UseMongoDBMonitor(() => { var str = Configuration.GetValue<string>("MongoDB:Str"); var dbName = Configuration.GetValue<string>("MongoDB:DatabaseName"); return new MonogoDbConfig(str, dbName); });//.UseZK(); var serviceProvider = services.BuildServiceProvider(); var loggerFactory = serviceProvider.GetRequiredService<ILoggerFactory>(); //configure NLog loggerFactory.AddNLog(new NLogProviderOptions { CaptureMessageTemplates = true, CaptureMessageProperties = true }); loggerFactory.ConfigureNLog("NLog.config"); return serviceProvider; }
b、配置文件内容
{ "NetCoreRpc": { "RequestTimeouMillis": 10000, "Default": "192.168.129.117:12345", //"Group": [ // { // "NameSpace": "", // "Address": "127.0.0.1:12345" // } //], "Zookeeper": { "Connection": "192.168.100.34:2181", "ParentName": "/NetCoreRpc/ClientTest" } }, "MongoDB": { "Str": "mongodb://root:root@192.168.100.125:27017", "DatabaseName": "Rpc_Monitor" } }
配置服务端地址,也可以根据类的名字来配置服务端地址,因为一个客户端在业务多的时候可能调用了多个服务端,所以提供了根据类型的名字来配置服务端地址
c、如何开始调用
首先接口类和Model类的命名控件必须要与服务端一致,比如例子中的IStudentApplication与TestModel这两个。
然后通过代理类来实例化接口类,然后调用对应的方法即可。
private static void Send() { var studentApplication = ProxyFactory.Create<IStudentApplication>(); Console.WriteLine(studentApplication.Age()); Console.WriteLine(studentApplication.IsYongPeople(15)); var runTask = studentApplication.RunAsync(111); studentApplication.Say("Hello world"); studentApplication.Say(Encoding.UTF8.GetBytes("Hi!")); Console.WriteLine(Encoding.UTF8.GetString(studentApplication.Say())); var test = studentApplication.Test(); Console.WriteLine(test.ToString()); studentApplication.Sleep(); Console.WriteLine(runTask.Result); }
framework版本与.netcore版本大同小异,具体的实际使用请参考下各个项目的Test文件。
五、调用案例结果
六、服务端监控
监控应用还没有完善好,后续会完善的,对了监控应用必须基于MongoDB。
七、项目开源地址
https://github.com/yjqGitHub/NetCoreRpc 欢迎大家来吐槽,提建议,如果有兴趣一起来完善的就更好了。
还有Nuget上的版本还暂未发布,原先发布的还不是最新代码
以上是关于一个能够在Asp.Net和Asp.NetCore之间能够互相通讯的Rpc的主要内容,如果未能解决你的问题,请参考以下文章
asp.net core 系列之Response caching 之 Distributed caching
在Linux环境下使用Apache部署ASP.NET Core