netcore 基于 DispatchProxy 实现一个简单Rpc远程调用
前言
netcore 发布以来,一直很关注netcore的进程。目前在公司负责的网站也历经波折的全部有.net framework 4.0 全部切换到netcore 2.2 版本中。虽然过程遇到的坑不少,但好在最后坚持下来。目前系统全部运行稳定运行在k8s。虽然目前已经用netcore 码了不少业务代码,但总觉得很多新的语言特性、新的api没有使用到,为了学习netcore,决定做造一些简单的轮子,顺便学习下网络编程。
关于Rpc
RPC(Remote Procedure Call)—远程过程调用,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。RPC协议假定某些传输协议的存在,如TCP或UDP,为通信程序之间携带信息数据。在OSI网络通信模型中,RPC跨越了传输层和应用层。RPC使得开发包括网络分布式多程序在内的应用程序更加容易。【百度百科】
实现步骤
-
网络传输
- 使用netcore 新的api System.IO.Pipelines 实现了一个基于TCP传输组件 组件地址
-
序列化、反序列化
- 使用简单的netcore3.0自带的System.Text.Json 实现【只为实现功能,性能可能不行】
-
服务注册与获取
-
使用netcore自带的DI组件Microsoft.Extensions.DependencyInjection
-
服务注册
private static void RegisterIService(Assembly assembly) { var serviceCollection = new ServiceCollection(); var classTypes = assembly .GetTypes() .Where(type => type.IsClass && type.IsPublic && typeof(IRpcService).IsAssignableFrom(type)); foreach (var classType in classTypes) { var interfaceType = classType.GetInterfaces().FirstOrDefault(); serviceCollection.AddSingleton(interfaceType, classType); Console.WriteLine($"注册服务:{interfaceType.FullName},{classType.Name}"); } var provider = serviceCollection.BuildServiceProvider(); RpcServiceLocator.Init(provider, assembly); }
-
通过类名获取类型,之后使用GetService获取注册的服务实例
-
-
代理类生成
- 使用 DispatchProxy 动态生成代理类
使用方法
-
服务端
//获取需要注册的服务所在的程序集 var serviceAssembly = Assembly.GetAssembly(typeof(IUserService)); serviceCollection.AddRpcServer(configuration, serviceAssembly); var serviceProvider = serviceCollection.BuildServiceProvider(); var server = serviceProvider.GetService<RpcServer>(); await server.StartAsync();
-
客户端
var serviceCollection = new ServiceCollection(); var configuration = BuildConfiguration(); serviceCollection.AddLogging(configure => configure.AddConsole()); serviceCollection.AddRpcClient(configuration); var serviceProvider = serviceCollection.BuildServiceProvider(); var client = serviceProvider.GetService<RpcClient>(); await client.StartAsync(); var userService = client.CreateProxy<IUserService>(); for (int i = 0; i < 100; i++) { var result = userService.GetUserNameById(new TestParam { Id = 1.ToString() }); }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】凌霞软件回馈社区,携手博客园推出1Panel与Halo联合会员
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步