123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409 |
- using Sers.Core.Module.App;
- using Vit.Core.Module.Log;
- using System;
- using System.Reflection;
- using Vit.Extensions;
- using Sers.Core.Module.PubSub;
- using System.Collections.Generic;
- using Sers.Core.Module.Api.LocalApi;
- using Sers.Core.Module.Api;
- using Sers.ServiceCenter.ApiCenter;
- using Newtonsoft.Json.Linq;
- using Sers.Core.Module.Env;
- using Sers.Core.Module.Message;
- using Sers.ServiceCenter.Entity;
- using System.Linq;
- using Sers.Core.CL.CommunicationManage;
- using Sers.Core.CL.MessageOrganize;
- using System.Threading.Tasks;
- using Sers.SersLoader;
- using Sers.Core.Module.App.AppEvent;
- using System.Runtime.CompilerServices;
- namespace Sers.ServiceCenter
- {
- public class ServiceCenter
- {
- #region static
- public static readonly ServiceCenter Instance = new ServiceCenter();
- public static bool IsRunning => SersApplication.IsRunning;
- //(x.1) Init
- public static void Init()
- {
- Instance.InitCenter();
- }
- //(x.3)
- public static bool Start()
- {
- return Instance.StartCenter();
- }
- //(x.4)
- public static void RunAwait()
- {
- SersApplication.RunAwait();
- }
- //(x.5)
- public static void Stop()
- {
- Instance.StopCenter();
- }
- #endregion
- public ServiceCenter()
- {
- connForLocalStationService = new OrganizeConnection(localApiService);
- appEventList = AppEventLoader.LoadAppEvent(Vit.Core.Util.ConfigurationManager.ConfigurationManager.Instance.GetByPath<JArray>("Sers.AppEvent"))
- ?.ToList();
- }
- #region (x.1) 成员对象
- List<IAppEvent> appEventList { get; set; }
- public ApiCenterService apiCenterService { get; set; }
- private readonly CommunicationManageServer communicationManage = new CommunicationManageServer();
- private readonly ILocalApiService localApiService = LocalApiServiceFactory.CreateLocalApiService();
- private readonly IOrganizeConnection connForLocalStationService;
- #region class OrganizeConnection For LocalStationService
- class OrganizeConnection : IOrganizeConnection
- {
- public string connTag { get; set; }
- ILocalApiService localApiService;
- public OrganizeConnection(ILocalApiService localApiService)
- {
- this.localApiService = localApiService;
- }
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public void SendRequestAsync(Object sender, Vit.Core.Util.Pipelines.ByteData requestData, Action<object, Vit.Core.Util.Pipelines.ByteData> callback)
- {
- localApiService.InvokeApiAsync(sender, new ApiMessage(requestData.ToArraySegment()), (sender_, apiReplyMessage) =>
- {
- callback(sender_,apiReplyMessage.Package());
- });
- }
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public void SendMessageAsync(Vit.Core.Util.Pipelines.ByteData message)
- {
- MessageClient.Instance.OnGetMessage(this, message.ToArraySegment());
- }
- public void Close()
- {
- ServiceCenter.Instance.StopCenter();
- }
- }
- #endregion
- #endregion
- #region (x.2) InitCenter
- public void InitCenter()
- {
- Logger.Info("初始化ServiceCenter...");
- //(x.0) appEvent BeforeStart
- appEventList?.ForEach(ev=>ev.BeforeStart());
- #region (x.1)CL add builder for Iocp、ThreadWait
- communicationManage.BeforeBuildOrganize = (JObject[] configs, List<IOrganizeServer> organizeList) =>
- {
- var builderTypeList = new[] {
- typeof(Sers.CL.Socket.Iocp.OrganizeServerBuilder),
- typeof(Sers.CL.Socket.ThreadWait.OrganizeServerBuilder)
- };
- foreach (var config in configs)
- {
- var className = config["className"].ConvertToString();
- var type = builderTypeList.FirstOrDefault(t => t.FullName == className);
- if (type == null) continue;
- var builder = Activator.CreateInstance(type) as IOrganizeServerBuilder;
- if (builder == null) continue;
- builder.Build(organizeList, config);
- config["className"] = null;
- }
- };
- #endregion
- //(x.2)localApiService
- localApiService.Init();
- //(x.3)UsageReporter
- UsageReporter.UseUsageReporter();
- }
- #endregion
- #region (x.3) LoadApi
- /// <summary>
- /// 从配置文件(appsettings.json::Sers.LocalApiService.ApiLoaders ) 加载api加载器并加载api
- /// 从配置文件(appsettings.json::Sers.LocalApiService.StaticFileMap)加载静态文件映射器
- /// </summary>
- public void LoadApi()
- {
- localApiService.LoadApi_StaticFiles();
- localApiService.LoadApi();
- }
- /// <summary>
- /// 调用SsApi加载器加载api
- /// </summary>
- /// <param name="config"></param>
- public void LoadSsApi(ApiLoaderConfig config)
- {
- localApiService.LoadSersApi(config);
- }
- /// <summary>
- /// 调用SsApi加载器加载api
- /// </summary>
- /// <param name="assembly"></param>
- /// <param name="config"></param>
- public void LoadSsApi(Assembly assembly, ApiLoaderConfig config = null)
- {
- if (null == config) config = new ApiLoaderConfig();
- config.assembly = assembly;
- LoadSsApi(config);
- }
- #endregion
- #region (x.4) StartCenter
- public bool StartCenter()
- {
- Logger.Info("[ServiceCenter] starting ...");
- //(x.0) appEvent OnStart
- appEventList?.ForEach(ev => ev.OnStart());
- #region (x.1)注册主程序退出回调
- AppDomain.CurrentDomain.ProcessExit += (s, e) =>
- {
- StopCenter();
- };
- #endregion
- #region (x.2)CL 注册回调
- // 注册消息订阅 MessageCenterService
- communicationManage.conn_OnGetMessage = MessageCenterService.Instance.OnGetMessage;
- communicationManage.conn_OnGetRequest = apiCenterService.CallApiAsync;
- communicationManage.Conn_OnConnected = (IOrganizeConnection conn) =>
- {
- Logger.Info("[CL] OnConnected", new { connTag = conn.connTag });
- };
- communicationManage.Conn_OnDisconnected = (IOrganizeConnection conn) =>
- {
- Logger.Info("[CL] OnDisconnected", new { connTag = conn.connTag });
- MessageCenterService.Instance.Conn_OnDisconnected(conn);
- apiCenterService.ServiceStation_Remove(conn);
- };
- #endregion
- #region (x.3)注册 localApiService 到 apiCenterService
- {
- Logger.Info("[ServiceCenter] regist localApiService to apiCenterService...");
- var serviceStationData = new
- {
- serviceStationInfo = SersApplication.serviceStationInfo,
- deviceInfo = SersApplication.deviceInfo,
- localApiService.apiNodes
- };
- var serviceStation = serviceStationData.ConvertBySerialize<ServiceStation>();
- serviceStation.connection = connForLocalStationService;
- apiCenterService.ServiceStation_Regist(serviceStation);
- #region (x.x.2)后台获取机器码,并向服务中心提交(获取机器码比较耗时,故后台获取)
- Task.Run(() => {
- try
- {
- //(x.x.x.1)计算 DeviceUnqueKey 和 ServiceStationUnqueKey
- SersApplication.CalculateUniquekey();
- //(x.x.x.2)构建api参数
- var strServiceStationData = new
- {
- serviceStationInfo = SersApplication.serviceStationInfo,
- deviceInfo = SersApplication.deviceInfo
- }.Serialize();
- serviceStation = strServiceStationData.ConvertBySerialize<ServiceStation>();
- serviceStation.connection = connForLocalStationService;
- //(x.x.x.3)调用api
- apiCenterService.ServiceStation_UpdateStationInfo(serviceStation);
- }
- catch (Exception ex)
- {
- Logger.Error(ex);
- }
- });
- #endregion
- }
- #endregion
- #region (x.4)CL Start
- Logger.Info("[CL] starting...");
- if (!communicationManage.Start())
- {
- Logger.Info("[CL] start - failed");
- return false;
- }
- Logger.Info("[CL] started");
- #endregion
- //(x.5)
- localApiService.Start();
- #region (x.6) 初始化ApiClient
- Action<ApiMessage, Action<ArraySegment<byte>>> OnSendRequest = ((apiRequestMessage,callback) =>
- {
- apiCenterService.CallApiAsync(connForLocalStationService, null, apiRequestMessage,
- (sender, replyData) =>
- {
- callback(replyData.ToArraySegment());
- }
- );
- });
- ApiClient.SetOnSendRequest(new[] { OnSendRequest },communicationManage.requestTimeoutMs);
- #endregion
- #region (x.7) 桥接MessageClient 和 MessageCenterService
- MessageClient.Instance.OnSendMessage = (Vit.Core.Util.Pipelines.ByteData messageData) =>
- {
- MessageCenterService.Instance.OnGetMessage(connForLocalStationService, messageData.ToBytes().BytesToArraySegmentByte());
- };
- #endregion
- //(x.8) 调用SersApp事件
- SersApplication.ResistConsoleCancelKey(Stop);
- SersApplication.OnStart();
- Logger.Info("[ServiceCenter] started");
- //(x.9) appEvent AfterStart
- appEventList?.ForEach(ev => ev.AfterStart());
- return true;
- }
- #endregion
- #region (x.5) StopCenter
- public void StopCenter()
- {
- Logger.Info("[ServiceCenter] stop...");
- //(x.1) appEvent BeforeStop
- appEventList?.ForEach(ev => ev.BeforeStop());
- //(x.2)stop service
- if (SersApplication.IsRunning)
- {
- #region CommunicationManage stop
- Logger.Info("[CL] stop...");
- try
- {
- communicationManage.Stop();
- }
- catch (Exception ex)
- {
- Logger.Error(ex);
- }
- Logger.Info("[CL] stoped");
- #endregion
- Logger.Info("[LocalApiService] stop...");
- try
- {
- localApiService.Stop();
- }
- catch (Exception ex)
- {
- Logger.Error(ex);
- }
- Logger.Info("[LocalApiService] stoped");
- }
- Logger.Info("[ServiceCenter] stoped");
- //(x.3) appEvent AfterStop
- appEventList?.ForEach(ev => ev.AfterStop());
- //(x.4)调用SersApp 事件
- SersApplication.OnStop();
-
- }
- #endregion
- }
- }
|