ServiceCenter.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409
  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. 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 ILocalApiService localApiService = LocalApiServiceFactory.CreateLocalApiService();
  61. private readonly IOrganizeConnection connForLocalStationService;
  62. #region class OrganizeConnection For LocalStationService
  63. class OrganizeConnection : IOrganizeConnection
  64. {
  65. public string connTag { get; set; }
  66. ILocalApiService localApiService;
  67. public OrganizeConnection(ILocalApiService localApiService)
  68. {
  69. this.localApiService = localApiService;
  70. }
  71. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  72. public void SendRequestAsync(Object sender, Vit.Core.Util.Pipelines.ByteData requestData, Action<object, Vit.Core.Util.Pipelines.ByteData> callback)
  73. {
  74. localApiService.InvokeApiAsync(sender, new ApiMessage(requestData.ToArraySegment()), (sender_, apiReplyMessage) =>
  75. {
  76. callback(sender_,apiReplyMessage.Package());
  77. });
  78. }
  79. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  80. public void SendMessageAsync(Vit.Core.Util.Pipelines.ByteData message)
  81. {
  82. MessageClient.Instance.OnGetMessage(this, message.ToArraySegment());
  83. }
  84. public void Close()
  85. {
  86. ServiceCenter.Instance.StopCenter();
  87. }
  88. }
  89. #endregion
  90. #endregion
  91. #region (x.2) InitCenter
  92. public void InitCenter()
  93. {
  94. Logger.Info("初始化ServiceCenter...");
  95. //(x.0) appEvent BeforeStart
  96. appEventList?.ForEach(ev=>ev.BeforeStart());
  97. #region (x.1)CL add builder for Iocp、ThreadWait
  98. communicationManage.BeforeBuildOrganize = (JObject[] configs, List<IOrganizeServer> organizeList) =>
  99. {
  100. var builderTypeList = new[] {
  101. typeof(Sers.CL.Socket.Iocp.OrganizeServerBuilder),
  102. typeof(Sers.CL.Socket.ThreadWait.OrganizeServerBuilder)
  103. };
  104. foreach (var config in configs)
  105. {
  106. var className = config["className"].ConvertToString();
  107. var type = builderTypeList.FirstOrDefault(t => t.FullName == className);
  108. if (type == null) continue;
  109. var builder = Activator.CreateInstance(type) as IOrganizeServerBuilder;
  110. if (builder == null) continue;
  111. builder.Build(organizeList, config);
  112. config["className"] = null;
  113. }
  114. };
  115. #endregion
  116. //(x.2)localApiService
  117. localApiService.Init();
  118. //(x.3)UsageReporter
  119. UsageReporter.UseUsageReporter();
  120. }
  121. #endregion
  122. #region (x.3) LoadApi
  123. /// <summary>
  124. /// 从配置文件(appsettings.json::Sers.LocalApiService.ApiLoaders ) 加载api加载器并加载api
  125. /// 从配置文件(appsettings.json::Sers.LocalApiService.StaticFileMap)加载静态文件映射器
  126. /// </summary>
  127. public void LoadApi()
  128. {
  129. localApiService.LoadApi_StaticFiles();
  130. localApiService.LoadApi();
  131. }
  132. /// <summary>
  133. /// 调用SsApi加载器加载api
  134. /// </summary>
  135. /// <param name="config"></param>
  136. public void LoadSsApi(ApiLoaderConfig config)
  137. {
  138. localApiService.LoadSersApi(config);
  139. }
  140. /// <summary>
  141. /// 调用SsApi加载器加载api
  142. /// </summary>
  143. /// <param name="assembly"></param>
  144. /// <param name="config"></param>
  145. public void LoadSsApi(Assembly assembly, ApiLoaderConfig config = null)
  146. {
  147. if (null == config) config = new ApiLoaderConfig();
  148. config.assembly = assembly;
  149. LoadSsApi(config);
  150. }
  151. #endregion
  152. #region (x.4) StartCenter
  153. public bool StartCenter()
  154. {
  155. Logger.Info("[ServiceCenter] starting ...");
  156. //(x.0) appEvent OnStart
  157. appEventList?.ForEach(ev => ev.OnStart());
  158. #region (x.1)注册主程序退出回调
  159. AppDomain.CurrentDomain.ProcessExit += (s, e) =>
  160. {
  161. StopCenter();
  162. };
  163. #endregion
  164. #region (x.2)CL 注册回调
  165. // 注册消息订阅 MessageCenterService
  166. communicationManage.conn_OnGetMessage = MessageCenterService.Instance.OnGetMessage;
  167. communicationManage.conn_OnGetRequest = apiCenterService.CallApiAsync;
  168. communicationManage.Conn_OnConnected = (IOrganizeConnection conn) =>
  169. {
  170. Logger.Info("[CL] OnConnected", new { connTag = conn.connTag });
  171. };
  172. communicationManage.Conn_OnDisconnected = (IOrganizeConnection conn) =>
  173. {
  174. Logger.Info("[CL] OnDisconnected", new { connTag = conn.connTag });
  175. MessageCenterService.Instance.Conn_OnDisconnected(conn);
  176. apiCenterService.ServiceStation_Remove(conn);
  177. };
  178. #endregion
  179. #region (x.3)注册 localApiService 到 apiCenterService
  180. {
  181. Logger.Info("[ServiceCenter] regist localApiService to apiCenterService...");
  182. var serviceStationData = new
  183. {
  184. serviceStationInfo = SersApplication.serviceStationInfo,
  185. deviceInfo = SersApplication.deviceInfo,
  186. localApiService.apiNodes
  187. };
  188. var serviceStation = serviceStationData.ConvertBySerialize<ServiceStation>();
  189. serviceStation.connection = connForLocalStationService;
  190. apiCenterService.ServiceStation_Regist(serviceStation);
  191. #region (x.x.2)后台获取机器码,并向服务中心提交(获取机器码比较耗时,故后台获取)
  192. Task.Run(() => {
  193. try
  194. {
  195. //(x.x.x.1)计算 DeviceUnqueKey 和 ServiceStationUnqueKey
  196. SersApplication.CalculateUniquekey();
  197. //(x.x.x.2)构建api参数
  198. var strServiceStationData = new
  199. {
  200. serviceStationInfo = SersApplication.serviceStationInfo,
  201. deviceInfo = SersApplication.deviceInfo
  202. }.Serialize();
  203. serviceStation = strServiceStationData.ConvertBySerialize<ServiceStation>();
  204. serviceStation.connection = connForLocalStationService;
  205. //(x.x.x.3)调用api
  206. apiCenterService.ServiceStation_UpdateStationInfo(serviceStation);
  207. }
  208. catch (Exception ex)
  209. {
  210. Logger.Error(ex);
  211. }
  212. });
  213. #endregion
  214. }
  215. #endregion
  216. #region (x.4)CL Start
  217. Logger.Info("[CL] starting...");
  218. if (!communicationManage.Start())
  219. {
  220. Logger.Info("[CL] start - failed");
  221. return false;
  222. }
  223. Logger.Info("[CL] started");
  224. #endregion
  225. //(x.5)
  226. localApiService.Start();
  227. #region (x.6) 初始化ApiClient
  228. Action<ApiMessage, Action<ArraySegment<byte>>> OnSendRequest = ((apiRequestMessage,callback) =>
  229. {
  230. apiCenterService.CallApiAsync(connForLocalStationService, null, apiRequestMessage,
  231. (sender, replyData) =>
  232. {
  233. callback(replyData.ToArraySegment());
  234. }
  235. );
  236. });
  237. ApiClient.SetOnSendRequest(new[] { OnSendRequest },communicationManage.requestTimeoutMs);
  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. }