using System; using System.Collections.Generic; using System.IO; using System.Linq; using JsonRpcLite.InProcess; using JsonRpcLite.Network; using JsonRpcLite.Rpc; using WingServerCommon.Service; using WingServerCommon.Log; using WingServerCommon.Config; using WingServerCommon.Config.Parameters; using WingInterfaceLibrary.OpLog; using WingCloudServer.InteractionCenter; using System.Runtime.Loader; using JsonRpcLite.Utilities; using System.Threading.Tasks; using WingInterfaceLibrary.Interface.DBInterface; using WingInterfaceLibrary.Interface; using Newtonsoft.Json; using WingInterfaceLibrary.Request.Authentication; using JsonRpcLite.Services; using WingInterfaceLibrary.Enum; using WingCloudServer.Plugin; using WingInterfaceLibrary.DTO.DistributedServerInfo; using CSScriptLib; using System.Reflection; namespace WingCloudServer { internal class WingServer { private JsonRpcServer _rpcHttpServer; private JsonRpcServer _rpcInProcessServer; private JsonRpcInProcessEngine _inProcessEngine; private JsonRpcHttpServerEngine _jsonRpcHttpServerEngine; private Dictionary _rpcServices; public WingServer(string host) { _rpcInProcessServer = new JsonRpcServer(); _inProcessEngine = new JsonRpcInProcessEngine(); _rpcInProcessServer.UseEngine(_inProcessEngine); _rpcHttpServer = new JsonRpcServer(); _jsonRpcHttpServerEngine = new JsonRpcHttpServerEngine(host); _rpcHttpServer.UseEngine(_jsonRpcHttpServerEngine); } private TokenVerifyPlugin _tokenVerifyPlugin; private IPAddressPlugin _ipAddressPlugin; private ServerListPlugin _serverListPlugin; /// /// Start server to load all service /// internal void Start() { InitializeServices(); //按注册顺序执行 _jsonRpcHttpServerEngine.RegisterPlugin(_tokenVerifyPlugin); _jsonRpcHttpServerEngine.RegisterPlugin(_ipAddressPlugin); _jsonRpcHttpServerEngine.RegisterPlugin(_serverListPlugin); _rpcInProcessServer.Start(); LoadDataAfterRegister(); _rpcHttpServer.Start(); } /// /// Stop server /// internal void Stop() { //TODO dispose service _rpcHttpServer.Stop(); _rpcInProcessServer.Stop(); } void InitializeServices() { var folder = Path.Combine(AppDomain.CurrentDomain.BaseDirectory); //initiaize rpc client pool var rpcClientPool = new JsonRpcClientPool(_inProcessEngine); var inProcessServicesString = ConfigurationManager.GetParammeter("Services", "InProcess").Value; var inProcessServices = inProcessServicesString.Split(','); var rpcHttpServicesString = ConfigurationManager.GetParammeter("Services", "JsonRpcHttp").Value; var rpcHttpServices = rpcHttpServicesString.Split(','); if (!Directory.Exists(folder)) { throw new NotSupportedException($"Folder {folder} not exist"); } //InitAIDiagnosis(); //InProcess service load and register to InPrcess rpc server _rpcServices = new Dictionary(); foreach (var service in inProcessServices) { var wingServiceType = LoadService(folder, service); var instance = Activator.CreateInstance(wingServiceType); _rpcServices.Add(wingServiceType, instance); var interfaces = wingServiceType.GetInterfaces(); foreach (var serviceInterface in interfaces) { if (serviceInterface == typeof(IDisposable)) { continue; } if (serviceInterface == typeof(IJsonRpcService)) { continue; } Logger.WriteLineInfo($"Registering type-{wingServiceType.Name}, interface-{serviceInterface.Name} to Rpc InProcess Server"); _rpcInProcessServer.RegisterService(serviceInterface, instance); } } var remoteRpcHttpServices = LoadRemoteServiceConfig(folder);//new RemoteServiceInfo[0]; rpcClientPool.Initialize(remoteRpcHttpServices.ToArray()); //Rpc http service load and register to rpc http server if (ConfigurationManager.IsDistributed) { if (ConfigurationManager.IsMaster) { var masterInteractionCenterService = new MasterInteractionCenterService(); _rpcHttpServer.RegisterService(typeof(IMasterInteractionCenterService), masterInteractionCenterService); masterInteractionCenterService.Load(rpcClientPool); } else { //TODO determin if we need to assess slave server on master server } } // AssemblyLoadContext.Default.Resolving += (assemblyLoadContext, assemblyName) => // { // //var path = _assemblyDependencyResolver.ResolveUnmanagedDllToPath(assemblyName.FullName); // Console.WriteLine($"LoadAssemblyDependencies :{assemblyLoadContext.Name} --- {assemblyName.Name}"); // return null; // }; foreach (var service in rpcHttpServices) { var wingServiceType = LoadService(folder, service); var instance = Activator.CreateInstance(wingServiceType); _rpcServices.Add(wingServiceType, instance); var interfaces = wingServiceType.GetInterfaces(); foreach (var serviceInterface in interfaces) { if (serviceInterface == typeof(IDisposable)) { continue; } if (serviceInterface == typeof(IJsonRpcService)) { continue; } Logger.WriteLineInfo($"Registering type-{wingServiceType.Name}, interface-{serviceInterface.Name} to Rpc Http Server"); _rpcHttpServer.RegisterService(serviceInterface, instance); } } //load service if distrubuted system if (ConfigurationManager.IsDistributed) { if (ConfigurationManager.IsMaster) { //_rpcHttpServer.RegisterService(IMaster); TODO } else { //动态注册副服务器实时同步服务 RegisterDynamicSlaveInteractionCenterService(rpcClientPool); } } //load services foreach (var service in _rpcServices) { var method = service.Key.GetMethod("Load"); method.Invoke(service.Value, new object[] { rpcClientPool }); } //最快服务器 var vinnoServerService = new VinnoServerService(); _rpcHttpServer.RegisterService(typeof(WingInterfaceLibrary.Interface.IVinnoServerService), vinnoServerService); vinnoServerService.Load(rpcClientPool); //plugin _tokenVerifyPlugin = new TokenVerifyPlugin(); _rpcHttpServer.RegisterService(typeof(ITokenVerifyPlugin), _tokenVerifyPlugin); _tokenVerifyPlugin.Load(rpcClientPool); _ipAddressPlugin = new IPAddressPlugin(); _rpcHttpServer.RegisterService(typeof(IIPAddressPlugin), _ipAddressPlugin); _ipAddressPlugin.Load(rpcClientPool); _serverListPlugin = new ServerListPlugin(); _rpcHttpServer.RegisterService(typeof(IServerListPlugin), _serverListPlugin); _serverListPlugin.Load(rpcClientPool); } //todo 待验证是否可以调用本地的service public void RegisterDynamicSlaveInteractionCenterService(JsonRpcClientPool rpcClientPool) { var eval = CSScript.Evaluator.ReferenceDomainAssemblies(DomainAssemblies.AllStaticNonGAC); var host = ConfigurationManager.Host.Replace("http:", "").Replace(".", "").Replace("/", ""); var str = @" using System; using System.Threading.Tasks; using WingServerCommon.Service; using WingInterfaceLibrary.OpLog; using System.Collections.Generic; using JsonRpcLite.Rpc; using WingInterfaceLibrary.Interface.DBInterface; using WingInterfaceLibrary.DB.Request; public interface IDynamicSlaveService" + host + @" { Task DynamicSlaveAsync(SyncReceiveServiceDataRequest request); } public class DynamicSlaveService : JsonRpcService,IDynamicSlaveService" + host + @" { protected ISlaveInteractionCenterService _slaveInteractionCenterService; public override void Load(JsonRpcClientPool jsonRpcClientPool) { base.Load(jsonRpcClientPool); _slaveInteractionCenterService = GetProxy(); } public async Task DynamicSlaveAsync(SyncReceiveServiceDataRequest request) { await _slaveInteractionCenterService.SyncReceiveMasterServiceDataAsync(request); return true; } } public class DynamicMethodClass { public void DynamicMethod(JsonRpcClientPool rpcClientPool,JsonRpcServer _rpcHttpServer){ var DynamicSlaveService = new DynamicSlaveService(); _rpcHttpServer.RegisterService(typeof(IDynamicSlaveService" + host + @"), DynamicSlaveService); DynamicSlaveService.Load(rpcClientPool); } } "; Assembly compilecode = eval.CompileCode(str); var ps = compilecode.GetType("css_root+DynamicMethodClass"); var obj = compilecode.CreateInstance("css_root+DynamicMethodClass"); var mes = ps.GetMethod("DynamicMethod"); mes.Invoke(obj, new object[] { rpcClientPool, _rpcHttpServer }); } void LoadDataAfterRegister() { foreach (var service in _rpcServices) { var method = service.Key.GetMethod("LoadAfterRegister"); method.Invoke(service.Value, null); } } private Type LoadService(string folder, object serviceName) { var file = Path.Combine(folder, $"{serviceName}.dll"); if (!Directory.Exists(folder)) { throw new NotSupportedException($"File {file} not exist"); } var assembly = AssemblyLoader.LoadAssemblyDependencies(file); var types = assembly.GetTypes(); var wingServiceType = types.FirstOrDefault(x => typeof(JsonRpcService).IsAssignableFrom(x) && x.IsClass && !x.IsAbstract); if (wingServiceType == null) { throw new NotImplementedException($"WingService not find in {file}"); } return wingServiceType; } /// /// 加载 远程服务 配置 /// /// private List LoadRemoteServiceConfig(string folder) { List resList = new List(); if (ConfigurationManager.IsDistributed) { if (ConfigurationManager.IsMaster) { DynamicRemoteSlaveService(resList); } else { var serviceInfo = new RemoteServiceInfo() { ServiceName = "IMasterInteractionCenterService", Url = ConfigurationManager.MasterUrl }; resList.Add(serviceInfo); } } var remoteConfig = ConfigurationManager.GetParammeter("Services", "Remote").Value; if (!string.IsNullOrEmpty(remoteConfig) && remoteConfig.Split(',').Length > 0) { var remoteList = remoteConfig.Split(','); foreach (var serviceInfo in remoteList) { var remoteArray = serviceInfo.Split('|'); var moduleName = remoteArray[0];//模块名称 var url = remoteArray[1];//URL var wingServiceType = LoadService(folder, remoteArray[0]); var interfaces = wingServiceType.GetInterfaces(); foreach (var serviceInterface in interfaces) { if (serviceInterface == typeof(IDisposable)) { continue; } if (serviceInterface == typeof(IJsonRpcService)) { continue; } var Info = new RemoteServiceInfo() { ServiceName = serviceInterface.Name, Url = url }; resList.Add(Info); } } } return resList; } public void DynamicRemoteSlaveService(List resList) { var slaveList = new List(); var host = ConfigurationManager.Host; var eval = CSScript.Evaluator.ReferenceDomainAssemblies(DomainAssemblies.AllStaticNonGAC); var str = @" using System; using System.Threading.Tasks; using WingServerCommon.Service; using WingInterfaceLibrary.OpLog; using System.Collections.Generic; using JsonRpcLite.Rpc; using WingInterfaceLibrary.Interface.DBInterface; using WingInterfaceLibrary.DB.Request; using WingInterfaceLibrary.DTO.DistributedServerInfo; using WingInterfaceLibrary.Request.DBRequest; using System.Linq; public class GetUrlListService : JsonRpcService { protected IDistributedServerInfoDBService _distributedServerInfoDBService; public override void Load(JsonRpcClientPool jsonRpcClientPool) { base.Load(jsonRpcClientPool); _distributedServerInfoDBService = GetProxy(); } public List GetSlaveList(string host,List slaveList) { var distributedServerInfoDBPagesRequest = new GetDistributedServerInfoDBPagesRequest(); distributedServerInfoDBPagesRequest.CurrentPage = 1; distributedServerInfoDBPagesRequest.PageSize = 9999; var result = _distributedServerInfoDBService.GetDistributedServerInfoPagesAsync(distributedServerInfoDBPagesRequest).Result; if (result != null && result.TotalCount > 0) { slaveList = result.PageData; slaveList = slaveList.Where(x => x.ServerUrl != host).ToList(); } return slaveList; } } "; Assembly compilecode = eval.CompileCode(str); var ps = compilecode.GetType("css_root+GetUrlListService"); var obj = compilecode.CreateInstance("css_root+GetUrlListService"); var mes = ps.GetMethod("GetSlaveList"); mes.Invoke(obj, new object[] { slaveList }); //动态注册副服务器服务 foreach (var item in slaveList) { var serviceInfo = new RemoteServiceInfo() { ServiceName = "IDynamicSlaveService" + item.ServerUrl.Replace("http:", "").Replace(".", "").Replace("/", ""), Url = ConfigurationManager.MasterUrl }; resList.Add(serviceInfo); } } /// /// 初始化AIDiagnosis /// private void InitAIDiagnosis() { try { var dllsRootPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "AIDiagnosis"); var destFolder = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Dependencies"); CopyFilesAndDirs(dllsRootPath, destFolder); } catch (Exception ex) { Logger.WriteLineError($"InitAIDiagnosis error:{ex}"); } } private void CopyFilesAndDirs(string sourceDir, string destDir) { if (!Directory.Exists(sourceDir)) { return; } if (!Directory.Exists(destDir)) { Directory.CreateDirectory(destDir); } string newPath; FileInfo fileInfo; string[] files = Directory.GetFiles(sourceDir); foreach (string path in files) { fileInfo = new FileInfo(path); newPath = destDir + "\\" + fileInfo.Name; File.Copy(path, newPath, true); } string[] dirs = Directory.GetDirectories(sourceDir); foreach (string path in dirs) { DirectoryInfo directory = new DirectoryInfo(path); string newDir = destDir + "\\" + directory.Name; CopyFilesAndDirs(path + "\\", newDir + "\\"); } } } }