zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    突然又想起了这首诗
    安装使用Androidx86打造快速流畅的Aandroid开发环境!
    解决电脑没插网线虚拟机无法桥接到主机
    使用WordPress更新通知服务,让搜索引擎知道你更新了,加快收录。
    php+apache+mysql环境配置时apache服务不能开启的解决
    WordPress备份的七种办法
    怎么在网站中正确使用JQuery代码
    如何让自己的博客在各搜索引擎中被搜索出来与快速收录
    轻松查看文件被哪个进程使用
    解密QQ非会员漫游聊天记录
  • 原文地址:https://www.cnblogs.com/zcode/p/easyrpc.html
Copyright © 2011-2022 走看看