WingServer.cs 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437
  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using System.Linq;
  5. using JsonRpcLite.InProcess;
  6. using JsonRpcLite.Network;
  7. using JsonRpcLite.Rpc;
  8. using WingServerCommon.Service;
  9. using WingServerCommon.Log;
  10. using WingServerCommon.Config;
  11. using WingServerCommon.Config.Parameters;
  12. using WingInterfaceLibrary.OpLog;
  13. using WingCloudServer.InteractionCenter;
  14. using System.Runtime.Loader;
  15. using JsonRpcLite.Utilities;
  16. using System.Threading.Tasks;
  17. using WingInterfaceLibrary.Interface.DBInterface;
  18. using WingInterfaceLibrary.Interface;
  19. using Newtonsoft.Json;
  20. using WingInterfaceLibrary.Request.Authentication;
  21. using JsonRpcLite.Services;
  22. using WingInterfaceLibrary.Enum;
  23. using WingCloudServer.Plugin;
  24. using WingInterfaceLibrary.DTO.DistributedServerInfo;
  25. using CSScriptLib;
  26. using System.Reflection;
  27. namespace WingCloudServer
  28. {
  29. internal class WingServer
  30. {
  31. private JsonRpcServer _rpcHttpServer;
  32. private JsonRpcServer _rpcInProcessServer;
  33. private JsonRpcInProcessEngine _inProcessEngine;
  34. private JsonRpcHttpServerEngine _jsonRpcHttpServerEngine;
  35. private Dictionary<Type, object> _rpcServices;
  36. public WingServer(string host)
  37. {
  38. _rpcInProcessServer = new JsonRpcServer();
  39. _inProcessEngine = new JsonRpcInProcessEngine();
  40. _rpcInProcessServer.UseEngine(_inProcessEngine);
  41. _rpcHttpServer = new JsonRpcServer();
  42. _jsonRpcHttpServerEngine = new JsonRpcHttpServerEngine(host);
  43. _rpcHttpServer.UseEngine(_jsonRpcHttpServerEngine);
  44. }
  45. private TokenVerifyPlugin _tokenVerifyPlugin;
  46. private IPAddressPlugin _ipAddressPlugin;
  47. private ServerListPlugin _serverListPlugin;
  48. /// <summary>
  49. /// Start server to load all service
  50. /// </summary>
  51. internal void Start()
  52. {
  53. InitializeServices();
  54. //按注册顺序执行
  55. _jsonRpcHttpServerEngine.RegisterPlugin(_tokenVerifyPlugin);
  56. _jsonRpcHttpServerEngine.RegisterPlugin(_ipAddressPlugin);
  57. _jsonRpcHttpServerEngine.RegisterPlugin(_serverListPlugin);
  58. _rpcInProcessServer.Start();
  59. LoadDataAfterRegister();
  60. _rpcHttpServer.Start();
  61. }
  62. /// <summary>
  63. /// Stop server
  64. /// </summary>
  65. internal void Stop()
  66. {
  67. //TODO dispose service
  68. _rpcHttpServer.Stop();
  69. _rpcInProcessServer.Stop();
  70. }
  71. void InitializeServices()
  72. {
  73. var folder = Path.Combine(AppDomain.CurrentDomain.BaseDirectory);
  74. //initiaize rpc client pool
  75. var rpcClientPool = new JsonRpcClientPool(_inProcessEngine);
  76. var inProcessServicesString = ConfigurationManager.GetParammeter<StringParameter>("Services", "InProcess").Value;
  77. var inProcessServices = inProcessServicesString.Split(',');
  78. var rpcHttpServicesString = ConfigurationManager.GetParammeter<StringParameter>("Services", "JsonRpcHttp").Value;
  79. var rpcHttpServices = rpcHttpServicesString.Split(',');
  80. if (!Directory.Exists(folder))
  81. {
  82. throw new NotSupportedException($"Folder {folder} not exist");
  83. }
  84. //InitAIDiagnosis();
  85. //InProcess service load and register to InPrcess rpc server
  86. _rpcServices = new Dictionary<Type, object>();
  87. foreach (var service in inProcessServices)
  88. {
  89. var wingServiceType = LoadService(folder, service);
  90. var instance = Activator.CreateInstance(wingServiceType);
  91. _rpcServices.Add(wingServiceType, instance);
  92. var interfaces = wingServiceType.GetInterfaces();
  93. foreach (var serviceInterface in interfaces)
  94. {
  95. if (serviceInterface == typeof(IDisposable))
  96. {
  97. continue;
  98. }
  99. if (serviceInterface == typeof(IJsonRpcService))
  100. {
  101. continue;
  102. }
  103. Logger.WriteLineInfo($"Registering type-{wingServiceType.Name}, interface-{serviceInterface.Name} to Rpc InProcess Server");
  104. _rpcInProcessServer.RegisterService(serviceInterface, instance);
  105. }
  106. }
  107. var remoteRpcHttpServices = LoadRemoteServiceConfig(folder);//new RemoteServiceInfo[0];
  108. rpcClientPool.Initialize(remoteRpcHttpServices.ToArray());
  109. //Rpc http service load and register to rpc http server
  110. if (ConfigurationManager.IsDistributed)
  111. {
  112. if (ConfigurationManager.IsMaster)
  113. {
  114. var masterInteractionCenterService = new MasterInteractionCenterService();
  115. _rpcHttpServer.RegisterService(typeof(IMasterInteractionCenterService), masterInteractionCenterService);
  116. masterInteractionCenterService.Load(rpcClientPool);
  117. }
  118. else
  119. {
  120. //TODO determin if we need to assess slave server on master server
  121. }
  122. }
  123. // AssemblyLoadContext.Default.Resolving += (assemblyLoadContext, assemblyName) =>
  124. // {
  125. // //var path = _assemblyDependencyResolver.ResolveUnmanagedDllToPath(assemblyName.FullName);
  126. // Console.WriteLine($"LoadAssemblyDependencies :{assemblyLoadContext.Name} --- {assemblyName.Name}");
  127. // return null;
  128. // };
  129. foreach (var service in rpcHttpServices)
  130. {
  131. var wingServiceType = LoadService(folder, service);
  132. var instance = Activator.CreateInstance(wingServiceType);
  133. _rpcServices.Add(wingServiceType, instance);
  134. var interfaces = wingServiceType.GetInterfaces();
  135. foreach (var serviceInterface in interfaces)
  136. {
  137. if (serviceInterface == typeof(IDisposable))
  138. {
  139. continue;
  140. }
  141. if (serviceInterface == typeof(IJsonRpcService))
  142. {
  143. continue;
  144. }
  145. Logger.WriteLineInfo($"Registering type-{wingServiceType.Name}, interface-{serviceInterface.Name} to Rpc Http Server");
  146. _rpcHttpServer.RegisterService(serviceInterface, instance);
  147. }
  148. }
  149. //load service if distrubuted system
  150. if (ConfigurationManager.IsDistributed)
  151. {
  152. if (ConfigurationManager.IsMaster)
  153. {
  154. //_rpcHttpServer.RegisterService(IMaster); TODO
  155. }
  156. else
  157. {
  158. //动态注册副服务器实时同步服务
  159. RegisterDynamicSlaveInteractionCenterService(rpcClientPool);
  160. }
  161. }
  162. //load services
  163. foreach (var service in _rpcServices)
  164. {
  165. var method = service.Key.GetMethod("Load");
  166. method.Invoke(service.Value, new object[] { rpcClientPool });
  167. }
  168. //最快服务器
  169. var vinnoServerService = new VinnoServerService();
  170. _rpcHttpServer.RegisterService(typeof(WingInterfaceLibrary.Interface.IVinnoServerService), vinnoServerService);
  171. vinnoServerService.Load(rpcClientPool);
  172. //plugin
  173. _tokenVerifyPlugin = new TokenVerifyPlugin();
  174. _rpcHttpServer.RegisterService(typeof(ITokenVerifyPlugin), _tokenVerifyPlugin);
  175. _tokenVerifyPlugin.Load(rpcClientPool);
  176. _ipAddressPlugin = new IPAddressPlugin();
  177. _rpcHttpServer.RegisterService(typeof(IIPAddressPlugin), _ipAddressPlugin);
  178. _ipAddressPlugin.Load(rpcClientPool);
  179. _serverListPlugin = new ServerListPlugin();
  180. _rpcHttpServer.RegisterService(typeof(IServerListPlugin), _serverListPlugin);
  181. _serverListPlugin.Load(rpcClientPool);
  182. }
  183. //todo 待验证是否可以调用本地的service
  184. public void RegisterDynamicSlaveInteractionCenterService(JsonRpcClientPool rpcClientPool)
  185. {
  186. var eval = CSScript.Evaluator.ReferenceDomainAssemblies(DomainAssemblies.AllStaticNonGAC);
  187. var host = ConfigurationManager.Host.Replace("http:", "").Replace(".", "").Replace("/", "");
  188. var str = @"
  189. using System;
  190. using System.Threading.Tasks;
  191. using WingServerCommon.Service;
  192. using WingInterfaceLibrary.OpLog;
  193. using System.Collections.Generic;
  194. using JsonRpcLite.Rpc;
  195. using WingInterfaceLibrary.Interface.DBInterface;
  196. using WingInterfaceLibrary.DB.Request;
  197. public interface IDynamicSlaveService" + host + @"
  198. {
  199. Task<bool> DynamicSlaveAsync(SyncReceiveServiceDataRequest request);
  200. }
  201. public class DynamicSlaveService : JsonRpcService,IDynamicSlaveService" + host + @"
  202. {
  203. protected ISlaveInteractionCenterService _slaveInteractionCenterService;
  204. public override void Load(JsonRpcClientPool jsonRpcClientPool)
  205. {
  206. base.Load(jsonRpcClientPool);
  207. _slaveInteractionCenterService = GetProxy<ISlaveInteractionCenterService>();
  208. }
  209. public async Task<bool> DynamicSlaveAsync(SyncReceiveServiceDataRequest request)
  210. {
  211. await _slaveInteractionCenterService.SyncReceiveMasterServiceDataAsync(request);
  212. return true;
  213. }
  214. }
  215. public class DynamicMethodClass
  216. {
  217. public void DynamicMethod(JsonRpcClientPool rpcClientPool,JsonRpcServer _rpcHttpServer){
  218. var DynamicSlaveService = new DynamicSlaveService();
  219. _rpcHttpServer.RegisterService(typeof(IDynamicSlaveService" + host + @"), DynamicSlaveService);
  220. DynamicSlaveService.Load(rpcClientPool);
  221. }
  222. }
  223. ";
  224. Assembly compilecode = eval.CompileCode(str);
  225. var ps = compilecode.GetType("css_root+DynamicMethodClass");
  226. var obj = compilecode.CreateInstance("css_root+DynamicMethodClass");
  227. var mes = ps.GetMethod("DynamicMethod");
  228. mes.Invoke(obj, new object[] { rpcClientPool, _rpcHttpServer });
  229. }
  230. void LoadDataAfterRegister()
  231. {
  232. foreach (var service in _rpcServices)
  233. {
  234. var method = service.Key.GetMethod("LoadAfterRegister");
  235. method.Invoke(service.Value, null);
  236. }
  237. }
  238. private Type LoadService(string folder, object serviceName)
  239. {
  240. var file = Path.Combine(folder, $"{serviceName}.dll");
  241. if (!Directory.Exists(folder))
  242. {
  243. throw new NotSupportedException($"File {file} not exist");
  244. }
  245. var assembly = AssemblyLoader.LoadAssemblyDependencies(file);
  246. var types = assembly.GetTypes();
  247. var wingServiceType = types.FirstOrDefault(x => typeof(JsonRpcService).IsAssignableFrom(x) && x.IsClass && !x.IsAbstract);
  248. if (wingServiceType == null)
  249. {
  250. throw new NotImplementedException($"WingService not find in {file}");
  251. }
  252. return wingServiceType;
  253. }
  254. /// <summary>
  255. /// 加载 远程服务 配置
  256. /// </summary>
  257. /// <returns></returns>
  258. private List<RemoteServiceInfo> LoadRemoteServiceConfig(string folder)
  259. {
  260. List<RemoteServiceInfo> resList = new List<RemoteServiceInfo>();
  261. if (ConfigurationManager.IsDistributed)
  262. {
  263. if (ConfigurationManager.IsMaster)
  264. {
  265. DynamicRemoteSlaveService(resList);
  266. }
  267. else
  268. {
  269. var serviceInfo = new RemoteServiceInfo()
  270. {
  271. ServiceName = "IMasterInteractionCenterService",
  272. Url = ConfigurationManager.MasterUrl
  273. };
  274. resList.Add(serviceInfo);
  275. }
  276. }
  277. var remoteConfig = ConfigurationManager.GetParammeter<StringParameter>("Services", "Remote").Value;
  278. if (!string.IsNullOrEmpty(remoteConfig) && remoteConfig.Split(',').Length > 0)
  279. {
  280. var remoteList = remoteConfig.Split(',');
  281. foreach (var serviceInfo in remoteList)
  282. {
  283. var remoteArray = serviceInfo.Split('|');
  284. var moduleName = remoteArray[0];//模块名称
  285. var url = remoteArray[1];//URL
  286. var wingServiceType = LoadService(folder, remoteArray[0]);
  287. var interfaces = wingServiceType.GetInterfaces();
  288. foreach (var serviceInterface in interfaces)
  289. {
  290. if (serviceInterface == typeof(IDisposable))
  291. {
  292. continue;
  293. }
  294. if (serviceInterface == typeof(IJsonRpcService))
  295. {
  296. continue;
  297. }
  298. var Info = new RemoteServiceInfo()
  299. {
  300. ServiceName = serviceInterface.Name,
  301. Url = url
  302. };
  303. resList.Add(Info);
  304. }
  305. }
  306. }
  307. return resList;
  308. }
  309. public void DynamicRemoteSlaveService(List<RemoteServiceInfo> resList)
  310. {
  311. var slaveList = new List<DistributedServerInfoDTO>();
  312. var host = ConfigurationManager.Host;
  313. var eval = CSScript.Evaluator.ReferenceDomainAssemblies(DomainAssemblies.AllStaticNonGAC);
  314. var str = @"
  315. using System;
  316. using System.Threading.Tasks;
  317. using WingServerCommon.Service;
  318. using WingInterfaceLibrary.OpLog;
  319. using System.Collections.Generic;
  320. using JsonRpcLite.Rpc;
  321. using WingInterfaceLibrary.Interface.DBInterface;
  322. using WingInterfaceLibrary.DB.Request;
  323. using WingInterfaceLibrary.DTO.DistributedServerInfo;
  324. using WingInterfaceLibrary.Request.DBRequest;
  325. using System.Linq;
  326. public class GetUrlListService : JsonRpcService
  327. {
  328. protected IDistributedServerInfoDBService _distributedServerInfoDBService;
  329. public override void Load(JsonRpcClientPool jsonRpcClientPool)
  330. {
  331. base.Load(jsonRpcClientPool);
  332. _distributedServerInfoDBService = GetProxy<IDistributedServerInfoDBService>();
  333. }
  334. public List<DistributedServerInfoDTO> GetSlaveList(string host,List<DistributedServerInfoDTO> slaveList)
  335. {
  336. var distributedServerInfoDBPagesRequest = new GetDistributedServerInfoDBPagesRequest();
  337. distributedServerInfoDBPagesRequest.CurrentPage = 1;
  338. distributedServerInfoDBPagesRequest.PageSize = 9999;
  339. var result = _distributedServerInfoDBService.GetDistributedServerInfoPagesAsync(distributedServerInfoDBPagesRequest).Result;
  340. if (result != null && result.TotalCount > 0)
  341. {
  342. slaveList = result.PageData;
  343. slaveList = slaveList.Where(x => x.ServerUrl != host).ToList();
  344. }
  345. return slaveList;
  346. }
  347. }
  348. ";
  349. Assembly compilecode = eval.CompileCode(str);
  350. var ps = compilecode.GetType("css_root+GetUrlListService");
  351. var obj = compilecode.CreateInstance("css_root+GetUrlListService");
  352. var mes = ps.GetMethod("GetSlaveList");
  353. mes.Invoke(obj, new object[] { slaveList });
  354. //动态注册副服务器服务
  355. foreach (var item in slaveList)
  356. {
  357. var serviceInfo = new RemoteServiceInfo()
  358. {
  359. ServiceName = "IDynamicSlaveService" + item.ServerUrl.Replace("http:", "").Replace(".", "").Replace("/", ""),
  360. Url = ConfigurationManager.MasterUrl
  361. };
  362. resList.Add(serviceInfo);
  363. }
  364. }
  365. /// <summary>
  366. /// 初始化AIDiagnosis
  367. /// </summary>
  368. private void InitAIDiagnosis()
  369. {
  370. try
  371. {
  372. var dllsRootPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "AIDiagnosis");
  373. var destFolder = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Dependencies");
  374. CopyFilesAndDirs(dllsRootPath, destFolder);
  375. }
  376. catch (Exception ex)
  377. {
  378. Logger.WriteLineError($"InitAIDiagnosis error:{ex}");
  379. }
  380. }
  381. private void CopyFilesAndDirs(string sourceDir, string destDir)
  382. {
  383. if (!Directory.Exists(sourceDir))
  384. {
  385. return;
  386. }
  387. if (!Directory.Exists(destDir))
  388. {
  389. Directory.CreateDirectory(destDir);
  390. }
  391. string newPath;
  392. FileInfo fileInfo;
  393. string[] files = Directory.GetFiles(sourceDir);
  394. foreach (string path in files)
  395. {
  396. fileInfo = new FileInfo(path);
  397. newPath = destDir + "\\" + fileInfo.Name;
  398. File.Copy(path, newPath, true);
  399. }
  400. string[] dirs = Directory.GetDirectories(sourceDir);
  401. foreach (string path in dirs)
  402. {
  403. DirectoryInfo directory = new DirectoryInfo(path);
  404. string newDir = destDir + "\\" + directory.Name;
  405. CopyFilesAndDirs(path + "\\", newDir + "\\");
  406. }
  407. }
  408. }
  409. }