ServiceCenter.cs 12 KB

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