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() });
    }
    

代码地址

git

posted @ 2019-09-12 17:24  zpz!!  阅读(625)  评论(0编辑  收藏  举报