本篇內容屬於非實用性(拿來即用)介紹,如對框架設計沒興趣的朋友,請略過。 html
繼續貼上以前的一張圖片 git
Attributes:用於標註該接口爲某一特性的方法體,當系統經過Microsoft.Extensions.DependencyInjection自動構建成功後,框架將自動掃描接口上標註過[RpcTagBundle]的接口,造成目標接口列表,以供下面的方法調用。程序員
Core:該核心分爲Server和Client以及核心通用三個部分組成:github
Client:主要用於經過Ip地址遠程調用的方法Invoke實現,以及遠程服務端的檢查檢查實現。web
Communally:通用方法庫,包括惟一ID生成器(用於標識每次請求所產生的惟一客戶端)、通用對象轉換器(將複雜對象轉換爲喜歡默認對象)、異常處理器、序列化生成器。json
Server:提供服務宿主,服務執行者、服務入口處理、服務管理、服務定位、服務管理工廠的接口及默認實現。api
Proxy:運行時預生成及客戶端動態代理模組的接口和方法實現。mvc
Routing:提供地址定位、服務描述、服務路由的接口和方法實現。app
Transport:基於protobuf-net和dotnettey構建的二進制序列化、和通訊管道和宿主的接口和實現。負載均衡
全部主要類均已接口的形式提供接口名稱,和已默認實現的具體方法體(虛方法),方便在這個基礎上進行擴展和重寫。
本節簡單介紹一下DotEasy.Rpc主框架的接口的做用。
Attribute: |---RpcTagBundleAttribute.cs Core: |---Client: |-------Address: |-----------IAddressResolver.cs |-------IRemoteInvokeService.cs |---Server: |-------IServiceEntryFactory.cs |-------IServiceEntryLocate.cs |-------IServiceEntryManager.cs |-------IServiceEntryProvider.cs |-------IServiceExecutor.cs |-------IServiceHost.cs Proxy: |---IServiceProxyFactory.cs |---IServiceProxyGenerater.cs Routing: |---IServiceRouteFactory.cs |---IServiceRouteManager.cs Transport: |-------Codec: |-----------ITransportMessageCodecFactory.cs |-----------ITransportMessageDecoder.cs |-----------ITransportMessageEncoder.cs |---IMessageListener.cs |---IMessageSender.cs
namespace doteasy.rpc.interfaces { [RpcTagBundle] public interface IUserService { Task<string> GetUserName(int id); Task<bool> Exists(int id); Task<int> GetUserId(string userName); Task<DateTime> GetUserLastSignInTime(int id); Task<IDictionary<string, string>> GetDictionary(); Task TryThrowException(); } }
namespace doteasy.rpc.implement { public class UserService : IUserService { public Task<string> GetUserName(int id) { return Task.FromResult($"我傳了一個int數字{id}."); } public Task<bool> Exists(int id) { return Task.FromResult(true); } public Task<int> GetUserId(string userName) { return Task.FromResult(1); } public Task<DateTime> GetUserLastSignInTime(int id) { return Task.FromResult(DateTime.Now); } public Task<IDictionary<string, string>> GetDictionary() { return Task.FromResult<IDictionary<string, string>>(new Dictionary<string, string> { { "key", "value" } }); } public Task TryThrowException() { throw new Exception("嘗試拋出異常!"); } } }
namespace doteasy.rpc.webserver.Controllers { [Produces("application/json")] [Route("api/Health")] public class HealthController : Controller { [HttpGet] public IActionResult Get() => Ok("ok"); } }
using System; using doteasy.rpc.implement; using doteasy.rpc.interfaces; using DotEasy.Rpc.Entry; using Microsoft.AspNetCore.Builder; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; namespace doteasy.rpc.webserver { public static class ConsulServerExtensions { public static IApplicationBuilder UseConsulServerExtensions(this IApplicationBuilder app, IConfiguration configuration) { if (app == null) throw new ArgumentNullException(nameof(app)); BaseServer baseServer = new BaseServer(configuration); //(1) baseServer.RegisterEvent += collection => collection.AddTransient<IUserService, UserService>(); //(2) baseServer.Start(); //(3) return app; } } }
{ "Hosting.urls": "http://127.0.0.1:5000", "Hosting.And.Rpc.Health.Check": "http://127.0.0.1:5000/api/health", "Rpc": { "IP": "127.0.0.1", "Port": 9881 }, "ServiceDescriptor": { "Name": "LZZ.DEV.ServerService" }, "ConsulRegister": { "IP": "127.0.0.1", "Port": 8500, "Timeout": 5 } }
using System; using System.Threading.Tasks; using doteasy.rpc.interfaces; using DotEasy.Rpc.Entry; namespace DotEasy.Client { class Program : BaseClient { static void Main() { new TestClient(); } } public class TestClient : BaseClient { public TestClient() { Task.Run(async () => { var userService = Proxy<IUserService>(); Console.WriteLine($"UserService.GetUserName:{await userService.GetUserName(1)}"); Console.WriteLine($"UserService.GetUserId:{await userService.GetUserId("rabbit")}"); Console.WriteLine($"UserService.GetUserLastSignInTime:{await userService.GetUserLastSignInTime(1)}"); Console.WriteLine($"UserService.Exists:{await userService.Exists(1)}"); Console.WriteLine($"UserService.GetDictionary:{(await userService.GetDictionary())["key"]}"); }).Wait(); } } }
info: DotEasy.Rpc.Core.Communally.Convertibles.Impl.DefaultTypeConvertibleService[0] 發現瞭如下類型轉換提供程序:DotEasy.Rpc.Core.Communally.Convertibles.Impl.DefaultTypeConvertibleProvider info: DotEasy.Rpc.Core.Communally.IdGenerator.Impl.DefaultServiceIdGenerator[0] 方法:System.Threading.Tasks.Task`1[System.String] GetUserName(Int32) 生成服務Id:doteasy.rpc.interfaces.IUserService.GetUserName_id info: DotEasy.Rpc.Core.Communally.IdGenerator.Impl.DefaultServiceIdGenerator[0] 方法:System.Threading.Tasks.Task`1[System.Boolean] Exists(Int32) 生成服務Id:doteasy.rpc.interfaces.IUserService.Exists_id info: DotEasy.Rpc.Core.Communally.IdGenerator.Impl.DefaultServiceIdGenerator[0] 方法:System.Threading.Tasks.Task`1[System.Int32] GetUserId(System.String) 生成服務Id:doteasy.rpc.interfaces.IUserService.GetUserId_userName info: DotEasy.Rpc.Core.Communally.IdGenerator.Impl.DefaultServiceIdGenerator[0] 方法:System.Threading.Tasks.Task`1[System.DateTime] GetUserLastSignInTime(Int32) 生成服務Id:doteasy.rpc.interfaces.IUserService.GetUserLastSignInTime_id info: DotEasy.Rpc.Core.Communally.IdGenerator.Impl.DefaultServiceIdGenerator[0] 方法:System.Threading.Tasks.Task`1[System.Collections.Generic.IDictionary`2[System.String,System.String]] GetDictionary() 生成服務Id:doteasy.rpc.interfaces.IUserService.GetDictionary info: DotEasy.Rpc.Core.Communally.IdGenerator.Impl.DefaultServiceIdGenerator[0] 方法:System.Threading.Tasks.Task TryThrowException() 生成服務Id:doteasy.rpc.interfaces.IUserService.TryThrowException info: DotEasy.Rpc.Core.Client.Address.Resolvers.Implementation.DefaultAddressResolver[0] 準備爲服務id:doteasy.rpc.interfaces.IUserService.GetUserName_id,解析可用地址 info: DotEasy.Rpc.Consul.ConsulServiceRouteManager[0] 準備獲取全部路由配置。 info: DotEasy.Rpc.Core.Client.Address.Resolvers.Implementation.DefaultAddressResolver[0] 根據服務id:doteasy.rpc.interfaces.IUserService.GetUserName_id,找到如下可用地址:127.0.0.1:9881 info: DotEasy.Rpc.Core.Client.Implementation.RemoteInvokeService[0] 使用地址:'127.0.0.1:9881'進行調用 info: DotEasy.Rpc.Transport.Impl.DefaultDotNettyTransportClientFactory[0] 準備爲服務端地址:127.0.0.1:9881建立客戶端。 info: DotEasy.Rpc.Transport.Impl.DefaultDotNettyTransportClientFactory[0] 準備發送消息。 info: DotEasy.Rpc.Transport.Impl.DefaultDotNettyTransportClientFactory[0] 準備獲取Id爲:0b720018feda4e4192937dfbb76eeb66的響應內容。 info: DotEasy.Rpc.Transport.Impl.DefaultDotNettyTransportClientFactory[0] 消息發送成功。 UserService.GetUserName:我傳了一個int數字1. info: DotEasy.Rpc.Core.Client.Address.Resolvers.Implementation.DefaultAddressResolver[0] 準備爲服務id:doteasy.rpc.interfaces.IUserService.GetUserId_userName,解析可用地址 info: DotEasy.Rpc.Consul.ConsulServiceRouteManager[0] 準備獲取全部路由配置。 info: DotEasy.Rpc.Core.Client.Address.Resolvers.Implementation.DefaultAddressResolver[0] 根據服務id:doteasy.rpc.interfaces.IUserService.GetUserId_userName,找到如下可用地址:127.0.0.1:9881 info: DotEasy.Rpc.Core.Client.Implementation.RemoteInvokeService[0] 使用地址:'127.0.0.1:9881'進行調用 info: DotEasy.Rpc.Transport.Impl.DefaultDotNettyTransportClientFactory[0] 準備爲服務端地址:127.0.0.1:9881建立客戶端。 info: DotEasy.Rpc.Transport.Impl.DefaultDotNettyTransportClientFactory[0] 準備發送消息。 info: DotEasy.Rpc.Transport.Impl.DefaultDotNettyTransportClientFactory[0] 準備獲取Id爲:e14b7606b4d54a66af81bfe3c7df46d4的響應內容。 info: DotEasy.Rpc.Transport.Impl.DefaultDotNettyTransportClientFactory[0] 消息發送成功。 info: DotEasy.Rpc.Core.Communally.Convertibles.Impl.DefaultTypeConvertibleService[0] 準備將 System.Int64 轉換爲:System.Int32 UserService.GetUserId:1 info: DotEasy.Rpc.Core.Client.Address.Resolvers.Implementation.DefaultAddressResolver[0] 準備爲服務id:doteasy.rpc.interfaces.IUserService.GetUserLastSignInTime_id,解析可用地址 info: DotEasy.Rpc.Consul.ConsulServiceRouteManager[0] 準備獲取全部路由配置。 info: DotEasy.Rpc.Core.Client.Address.Resolvers.Implementation.DefaultAddressResolver[0] 根據服務id:doteasy.rpc.interfaces.IUserService.GetUserLastSignInTime_id,找到如下可用地址:127.0.0.1:9881 info: DotEasy.Rpc.Core.Client.Implementation.RemoteInvokeService[0] 使用地址:'127.0.0.1:9881'進行調用 info: DotEasy.Rpc.Transport.Impl.DefaultDotNettyTransportClientFactory[0] 準備爲服務端地址:127.0.0.1:9881建立客戶端。 info: DotEasy.Rpc.Transport.Impl.DefaultDotNettyTransportClientFactory[0] 準備發送消息。 info: DotEasy.Rpc.Transport.Impl.DefaultDotNettyTransportClientFactory[0] 準備獲取Id爲:d0452b16caeb48ba877da5f69a31b2f8的響應內容。 info: DotEasy.Rpc.Transport.Impl.DefaultDotNettyTransportClientFactory[0] 消息發送成功。 UserService.GetUserLastSignInTime:2018/12/11 22:31:41 info: DotEasy.Rpc.Core.Client.Address.Resolvers.Implementation.DefaultAddressResolver[0] 準備爲服務id:doteasy.rpc.interfaces.IUserService.Exists_id,解析可用地址 info: DotEasy.Rpc.Consul.ConsulServiceRouteManager[0] 準備獲取全部路由配置。 info: DotEasy.Rpc.Core.Client.Address.Resolvers.Implementation.DefaultAddressResolver[0] 根據服務id:doteasy.rpc.interfaces.IUserService.Exists_id,找到如下可用地址:127.0.0.1:9881 info: DotEasy.Rpc.Core.Client.Implementation.RemoteInvokeService[0] 使用地址:'127.0.0.1:9881'進行調用 info: DotEasy.Rpc.Transport.Impl.DefaultDotNettyTransportClientFactory[0] 準備爲服務端地址:127.0.0.1:9881建立客戶端。 info: DotEasy.Rpc.Transport.Impl.DefaultDotNettyTransportClientFactory[0] 準備發送消息。 info: DotEasy.Rpc.Transport.Impl.DefaultDotNettyTransportClientFactory[0] 準備獲取Id爲:4e9a218c4abd4551845008d9bc23c31f的響應內容。 info: DotEasy.Rpc.Transport.Impl.DefaultDotNettyTransportClientFactory[0] 消息發送成功。 UserService.Exists:True info: DotEasy.Rpc.Core.Client.Address.Resolvers.Implementation.DefaultAddressResolver[0] 準備爲服務id:doteasy.rpc.interfaces.IUserService.GetDictionary,解析可用地址 info: DotEasy.Rpc.Consul.ConsulServiceRouteManager[0] 準備獲取全部路由配置。 info: DotEasy.Rpc.Core.Client.Address.Resolvers.Implementation.DefaultAddressResolver[0] 根據服務id:doteasy.rpc.interfaces.IUserService.GetDictionary,找到如下可用地址:127.0.0.1:9881 info: DotEasy.Rpc.Core.Client.Implementation.RemoteInvokeService[0] 使用地址:'127.0.0.1:9881'進行調用 info: DotEasy.Rpc.Transport.Impl.DefaultDotNettyTransportClientFactory[0] 準備爲服務端地址:127.0.0.1:9881建立客戶端。 info: DotEasy.Rpc.Transport.Impl.DefaultDotNettyTransportClientFactory[0] 準備發送消息。 info: DotEasy.Rpc.Transport.Impl.DefaultDotNettyTransportClientFactory[0] 準備獲取Id爲:a625fd4a6bd24e6b82983272b8894562的響應內容。 info: DotEasy.Rpc.Transport.Impl.DefaultDotNettyTransportClientFactory[0] 消息發送成功。 info: DotEasy.Rpc.Core.Communally.Convertibles.Impl.DefaultTypeConvertibleService[0] 準備將 Newtonsoft.Json.Linq.JObject 轉換爲:System.Collections.Generic.IDictionary`2[System.String,System.String] UserService.GetDictionary:value