ServiceCenter.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411
  1. using Sers.Core.Module.App;
  2. using Vit.Core.Module.Log;
  3. using System;
  4. using System.Reflection;
  5. using Vit.Extensions;
  6. using Sers.Core.Module.PubSub;
  7. using System.Collections.Generic;
  8. using Sers.Core.Module.Api.LocalApi;
  9. using Sers.Core.Module.Api;
  10. using Sers.ServiceCenter.ApiCenter;
  11. using Newtonsoft.Json.Linq;
  12. using Sers.Core.Module.Env;
  13. using Sers.Core.Module.Message;
  14. using Sers.ServiceCenter.Entity;
  15. using System.Linq;
  16. using Sers.Core.CL.CommunicationManage;
  17. using Sers.Core.CL.MessageOrganize;
  18. using System.Threading.Tasks;
  19. using Sers.SersLoader;
  20. using Sers.Core.Module.App.AppEvent;
  21. using System.Runtime.CompilerServices;
  22. using Vit.Extensions.Newtonsoft_Extensions;
  23. using Vit.Extensions.Json_Extensions;
  24. namespace Sers.ServiceCenter
  25. {
  26. public class ServiceCenter
  27. {
  28. #region static
  29. public static readonly ServiceCenter Instance = new ServiceCenter();
  30. public static bool IsRunning => SersApplication.IsRunning;
  31. //(x.1) Init
  32. public static void Init()
  33. {
  34. Instance.InitCenter();
  35. }
  36. //(x.3)
  37. public static bool Start()
  38. {
  39. return Instance.StartCenter();
  40. }
  41. //(x.4)
  42. public static void RunAwait()
  43. {
  44. SersApplication.RunAwait();
  45. }
  46. //(x.5)
  47. public static void Stop()
  48. {
  49. Instance.StopCenter();
  50. }
  51. #endregion
  52. public ServiceCenter()
  53. {
  54. connForLocalStationService = new OrganizeConnection(localApiService);
  55. appEventList = AppEventLoader.LoadAppEvent(Vit.Core.Util.ConfigurationManager.Appsettings.json.GetByPath<JArray>("Sers.AppEvent"))
  56. ?.ToList();
  57. }
  58. #region (x.1) 成员对象
  59. List<IAppEvent> appEventList { get; set; }
  60. public ApiCenterService apiCenterService { get; set; }
  61. private readonly CommunicationManageServer communicationManage = new CommunicationManageServer();
  62. private readonly ILocalApiService localApiService = LocalApiServiceFactory.CreateLocalApiService();
  63. private readonly IOrganizeConnection connForLocalStationService;
  64. #region class OrganizeConnection For LocalStationService
  65. class OrganizeConnection : IOrganizeConnection
  66. {
  67. ILocalApiService localApiService;
  68. public OrganizeConnection(ILocalApiService localApiService)
  69. {
  70. this.localApiService = localApiService;
  71. }
  72. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  73. public void SendRequestAsync(Object sender, Vit.Core.Util.Pipelines.ByteData requestData, Action<object, Vit.Core.Util.Pipelines.ByteData> callback)
  74. {
  75. localApiService.InvokeApiAsync(sender, new ApiMessage(requestData.ToArraySegment()), (sender_, apiReplyMessage) =>
  76. {
  77. callback(sender_, apiReplyMessage.Package());
  78. });
  79. }
  80. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  81. public void SendMessageAsync(Vit.Core.Util.Pipelines.ByteData message)
  82. {
  83. MessageClient.Instance.OnGetMessage(this, message.ToArraySegment());
  84. }
  85. public void Close()
  86. {
  87. ServiceCenter.Instance.StopCenter();
  88. }
  89. }
  90. #endregion
  91. #endregion
  92. #region (x.2) InitCenter
  93. public void InitCenter()
  94. {
  95. Logger.Info("[ServiceCenter] initializing", new { AssemblyVersion = SersEnvironment.GetEntryAssemblyVersion() });
  96. //(x.0) appEvent BeforeStart
  97. appEventList?.ForEach(ev => ev.BeforeStart());
  98. #region (x.1)CL add builder for Iocp、ThreadWait
  99. communicationManage.BeforeBuildOrganize = (JObject[] configs, List<IOrganizeServer> organizeList) =>
  100. {
  101. var builderTypeList = new[] {
  102. typeof(Sers.CL.Socket.Iocp.OrganizeServerBuilder),
  103. typeof(Sers.CL.Socket.ThreadWait.OrganizeServerBuilder)
  104. };
  105. foreach (var config in configs)
  106. {
  107. var className = config["className"].ConvertToString();
  108. var type = builderTypeList.FirstOrDefault(t => t.FullName == className);
  109. if (type == null) continue;
  110. var builder = Activator.CreateInstance(type) as IOrganizeServerBuilder;
  111. if (builder == null) continue;
  112. builder.Build(organizeList, config);
  113. config["className"] = null;
  114. }
  115. };
  116. #endregion
  117. //(x.2)localApiService
  118. localApiService.Init();
  119. //(x.3)UsageReporter
  120. UsageReporter.UseUsageReporter();
  121. }
  122. #endregion
  123. #region (x.3) LoadApi
  124. /// <summary>
  125. /// 从配置文件(appsettings.json::Sers.LocalApiService.ApiLoaders ) 加载api加载器并加载api
  126. /// 从配置文件(appsettings.json::Sers.LocalApiService.StaticFileMap)加载静态文件映射器
  127. /// </summary>
  128. public void LoadApi()
  129. {
  130. localApiService.LoadApi_StaticFiles();
  131. localApiService.LoadApi();
  132. }
  133. /// <summary>
  134. /// 调用SsApi加载器加载api
  135. /// </summary>
  136. /// <param name="config"></param>
  137. public void LoadSsApi(ApiLoaderConfig config)
  138. {
  139. localApiService.LoadSersApi(config);
  140. }
  141. /// <summary>
  142. /// 调用SsApi加载器加载api
  143. /// </summary>
  144. /// <param name="assembly"></param>
  145. /// <param name="config"></param>
  146. public void LoadSsApi(Assembly assembly, ApiLoaderConfig config = null)
  147. {
  148. if (null == config) config = new ApiLoaderConfig();
  149. config.assembly = assembly;
  150. LoadSsApi(config);
  151. }
  152. #endregion
  153. #region (x.4) StartCenter
  154. public bool StartCenter()
  155. {
  156. Logger.Info("[ServiceCenter] starting");
  157. //(x.0) appEvent OnStart
  158. appEventList?.ForEach(ev => ev.OnStart());
  159. #region (x.1)注册主程序退出回调
  160. AppDomain.CurrentDomain.ProcessExit += (s, e) =>
  161. {
  162. StopCenter();
  163. };
  164. #endregion
  165. #region (x.2)CL 注册回调
  166. // 注册消息订阅 MessageCenterService
  167. communicationManage.conn_OnGetMessage = MessageCenterService.Instance.OnGetMessage;
  168. communicationManage.conn_OnGetRequest = apiCenterService.CallApiAsync;
  169. communicationManage.Conn_OnConnected = (IOrganizeConnection conn) =>
  170. {
  171. Logger.Info("[CL] OnConnected", new { connKey = conn.GetConnKey() });
  172. };
  173. communicationManage.Conn_OnDisconnected = (IOrganizeConnection conn) =>
  174. {
  175. Logger.Info("[CL] OnDisconnected", new { connKey = conn.GetConnKey() });
  176. MessageCenterService.Instance.Conn_OnDisconnected(conn);
  177. apiCenterService.ServiceStation_Remove(conn);
  178. };
  179. #endregion
  180. #region (x.3)注册 localApiService 到 apiCenterService
  181. {
  182. Logger.Info("[ServiceCenter] registing localApiService to apiCenterService");
  183. var serviceStationData = new
  184. {
  185. serviceStationInfo = SersApplication.serviceStationInfo,
  186. deviceInfo = SersApplication.deviceInfo,
  187. localApiService.apiNodes
  188. };
  189. var serviceStation = serviceStationData.ConvertBySerialize<ServiceStation>();
  190. serviceStation.connection = connForLocalStationService;
  191. apiCenterService.ServiceStation_Regist(serviceStation);
  192. #region (x.x.2)后台获取机器码,并向服务中心提交(获取机器码比较耗时,故后台获取)
  193. Task.Run(() =>
  194. {
  195. try
  196. {
  197. //(x.x.x.1)计算 DeviceUnqueKey 和 ServiceStationUnqueKey
  198. SersApplication.CalculateUniquekey();
  199. //(x.x.x.2)构建api参数
  200. var strServiceStationData = new
  201. {
  202. serviceStationInfo = SersApplication.serviceStationInfo,
  203. deviceInfo = SersApplication.deviceInfo
  204. }.Serialize();
  205. serviceStation = strServiceStationData.ConvertBySerialize<ServiceStation>();
  206. serviceStation.connection = connForLocalStationService;
  207. //(x.x.x.3)调用api
  208. apiCenterService.ServiceStation_UpdateStationInfo(serviceStation);
  209. }
  210. catch (Exception ex)
  211. {
  212. Logger.Error(ex);
  213. }
  214. });
  215. #endregion
  216. }
  217. #endregion
  218. #region (x.4)CL Start
  219. Logger.Info("[CL] starting");
  220. if (!communicationManage.Start())
  221. {
  222. Logger.Error("[CL] start - failed");
  223. return false;
  224. }
  225. Logger.Info("[CL] started");
  226. #endregion
  227. //(x.5)
  228. localApiService.Start();
  229. #region (x.6) 初始化ApiClient
  230. Action<ApiMessage, Action<ArraySegment<byte>>> OnSendRequest = ((apiRequestMessage, callback) =>
  231. {
  232. apiCenterService.CallApiAsync(connForLocalStationService, null, apiRequestMessage,
  233. (sender, replyData) =>
  234. {
  235. callback(replyData.ToArraySegment());
  236. }
  237. );
  238. });
  239. ApiClient.SetOnSendRequest(new[] { OnSendRequest }, communicationManage.requestTimeoutMs);
  240. #endregion
  241. #region (x.7) 桥接MessageClient 和 MessageCenterService
  242. MessageClient.Instance.OnSendMessage = (Vit.Core.Util.Pipelines.ByteData messageData) =>
  243. {
  244. MessageCenterService.Instance.OnGetMessage(connForLocalStationService, messageData.ToBytes().BytesToArraySegmentByte());
  245. };
  246. #endregion
  247. //(x.8) 调用SersApp事件
  248. SersApplication.ResistConsoleCancelKey(Stop);
  249. SersApplication.OnStart();
  250. Logger.Info("[ServiceCenter] started");
  251. //(x.9) appEvent AfterStart
  252. appEventList?.ForEach(ev => ev.AfterStart());
  253. return true;
  254. }
  255. #endregion
  256. #region (x.5) StopCenter
  257. public void StopCenter()
  258. {
  259. Logger.Info("[ServiceCenter] stoping");
  260. //(x.1) appEvent BeforeStop
  261. appEventList?.ForEach(ev => ev.BeforeStop());
  262. //(x.2)stop service
  263. if (SersApplication.IsRunning)
  264. {
  265. #region CommunicationManage stop
  266. Logger.Info("[CL] stop...");
  267. try
  268. {
  269. communicationManage.Stop();
  270. }
  271. catch (Exception ex)
  272. {
  273. Logger.Error(ex);
  274. }
  275. Logger.Info("[CL] stoped");
  276. #endregion
  277. Logger.Info("[LocalApiService] stoping");
  278. try
  279. {
  280. localApiService.Stop();
  281. }
  282. catch (Exception ex)
  283. {
  284. Logger.Error(ex);
  285. }
  286. Logger.Info("[LocalApiService] stoped");
  287. }
  288. Logger.Info("[ServiceCenter] stoped");
  289. //(x.3) appEvent AfterStop
  290. appEventList?.ForEach(ev => ev.AfterStop());
  291. //(x.4)调用SersApp 事件
  292. SersApplication.OnStop();
  293. }
  294. #endregion
  295. }
  296. }