static void ShowOptionInfo(string root) { ZeroTrace.SystemLog("Option", "ZeroMQ", zmq.LibraryVersion); ZeroTrace.SystemLog("Option", "AppName", AppName); ZeroTrace.SystemLog("Option", "RootPath", root); string model; switch (Config.SpeedLimitModel) { default: model = "单线程:线程(1) 等待(0)"; break; case SpeedLimitType.ThreadCount: var max = (int)(Environment.ProcessorCount * Config.TaskCpuMultiple); if (max < 1) { max = 1; } model = $"按线程数限制:线程({Environment.ProcessorCount}×{Config.TaskCpuMultiple}={max}) 等待({Config.MaxWait})"; break; case SpeedLimitType.WaitCount: model = $"按等待数限制:线程(1) 等待({Config.MaxWait})"; break; } ZeroTrace.SystemLog("Option", model); ZeroTrace.SystemLog("Option", "ZeroCenter", Config.ZeroManageAddress, Config.ZeroMonitorAddress); }
/// <summary> /// 尝试安装站点 /// </summary> /// <param name="station"></param> /// <param name="type"></param> /// <returns></returns> public bool TryInstall(string station, string type) { if (ZeroApplication.Config.TryGetConfig(station, out _)) { return(true); } ZeroTrace.SystemLog(station, "No find,try install ..."); var r = CallCommand("install", type, station, station, station); if (!r.InteractiveSuccess) { ZeroTrace.WriteError(station, "Test install failed"); return(false); } if (r.State != ZeroOperatorStateType.Ok && r.TryGetValue(ZeroFrameType.Status, out var json)) { ZeroApplication.Config.UpdateConfig(station, json, out _); } ZeroTrace.SystemLog(station, "Is install ,try start it ..."); r = CallCommand("start", station); if (!r.InteractiveSuccess && r.State != ZeroOperatorStateType.Ok && r.State != ZeroOperatorStateType.Runing) { ZeroTrace.WriteError(station, "Can't start station"); return(false); } LoadConfig(station); ZeroTrace.SystemLog(station, "Station runing"); return(true); }
/// <summary> /// 系统关闭时调用 /// </summary> internal static void OnZeroEnd() { RaiseEvent(ZeroNetEventType.AppStop); using (OnceScope.CreateScope(ZeroObjects)) { ZeroTrace.SystemLog("[OnZeroEnd>>"); SystemManager.Instance.HeartLeft(); ApplicationState = StationState.Closing; if (HaseActiveObject) { Parallel.ForEach(ActiveObjects.ToArray(), obj => { try { ZeroTrace.SystemLog(obj.Name, "*Close"); obj.OnZeroEnd(); } catch (Exception e) { ZeroTrace.WriteException(obj.Name, e, "*Close"); } }); WaitAllObjectSemaphore(); } GC.Collect(); ApplicationState = StationState.Closed; ZeroTrace.SystemLog("<<OnZeroEnd]"); } }
/// <summary> /// 开始 /// </summary> public void Start() { ZeroTrace.SystemLog("ConnectionProxy", "Start"); RunTaskCancel = new CancellationTokenSource(); Task.Factory.StartNew(Run); _waitToken.Wait(); }
/// <summary> /// 开始 /// </summary> public void Start() { ZeroTrace.SystemLog($"{Config.StationName}(proxy)", "Start"); RunTaskCancel = new CancellationTokenSource(); Task.Factory.StartNew(Run); _waitToken.Wait(); }
/// <summary> /// 系统启动时调用 /// </summary> internal static void OnZeroStart() { Debug.Assert(!HaseActiveObject); using (OnceScope.CreateScope(ZeroObjects, ResetObjectActive)) { ZeroTrace.SystemLog("[OnZeroStart>>"); foreach (var obj in ZeroObjects.Values.ToArray()) { try { ZeroTrace.SystemLog(obj.Name, "*Start"); obj.OnZeroStart(); } catch (Exception e) { ZeroTrace.WriteException(obj.Name, e, "*Start"); } } WaitAllObjectSemaphore(); } SystemManager.Instance.HeartReady(); ApplicationState = StationState.Run; RaiseEvent(ZeroNetEventType.AppRun); ZeroTrace.SystemLog("<<OnZeroStart]"); }
/// <summary> /// 进入系统侦听 /// </summary> internal static void Monitor() { using (OnceScope.CreateScope(ZeroApplication.Config)) { } using (var poll = ZmqPool.CreateZmqPool()) { poll.Prepare(new[] { ZSocket.CreateSubscriberSocket(ZeroApplication.Config.ZeroMonitorAddress) }, ZPollEvent.In); ZeroTrace.SystemLog("Zero center in monitor..."); TaskEndSem.Release(); while (ZeroApplication.IsAlive) { if (!poll.Poll() || !poll.CheckIn(0, out var message)) { continue; } if (!message.Unpack(out var item)) { continue; } OnMessagePush(item.ZeroEvent, item.SubTitle, item.Content); } } TaskEndSem.Release(); }
/// <summary> /// 命令轮询 /// </summary> /// <returns></returns> private void Run() { _inprocPollSocket = ZSocket.CreateServiceSocket($"inproc://{Config.StationName}_Proxy", ZSocketType.ROUTER); _inprocPollSocket.Backlog = 4096; _callPollSocket = ZSocket.CreateClientSocket(Config.RequestAddress, ZSocketType.DEALER); WaitCount = 0; ZeroTrace.SystemLog($"{Config.StationName}(proxy)", "Listen"); _waitToken.Release(); using (var pool = ZmqPool.CreateZmqPool()) { pool.Prepare(new[] { _inprocPollSocket, _callPollSocket }, ZPollEvent.In); //SystemManager.Instance.HeartReady(StationName, RealName); while (!RunTaskCancel.Token.IsCancellationRequested) { if (!pool.Poll()) { continue; } CheckCall(pool); CheckResult(pool); } } _waitToken.Release(); }
/// <summary> /// 对象活动时登记 /// </summary> public static void OnGlobalStart(IZeroObject obj) { lock (GlobalObjects) { GlobalObjects.Add(obj); ZeroTrace.SystemLog(obj.Name, "GlobalStart"); } }
private static void center_start(string content) { if (Interlocked.CompareExchange(ref ZeroApplication._appState, StationState.Initialized, StationState.Failed) == StationState.Failed) { ZeroTrace.SystemLog("center_start", content); ZeroApplication.JoinCenter(); } }
private static void center_stop(string content) { if (ZeroApplication.ZerCenterStatus == ZeroCenterState.Destroy) { return; } ZeroApplication.ZerCenterStatus = ZeroCenterState.Destroy; ZeroTrace.SystemLog("center_stop ", content); }
private static void center_closing(string content) { if (Interlocked.CompareExchange(ref ZeroApplication._appState, StationState.Closing, StationState.Run) == StationState.Run) { ZeroTrace.SystemLog("center_close", content); ZeroApplication.RaiseEvent(ZeroNetEventType.CenterSystemClosing); ZeroApplication.ZerCenterStatus = ZeroCenterState.Closed; ZeroApplication.OnZeroEnd(); ZeroApplication.ApplicationState = StationState.Failed; } }
/// <summary> /// 对象活动时登记 /// </summary> public static void OnObjectActive(IZeroObject obj) { lock (ActiveObjects) { ActiveObjects.Add(obj); ZeroTrace.SystemLog(obj.Name, "Run"); if (ActiveObjects.Count + FailedObjects.Count == ZeroObjects.Count) { ActiveSemaphore.Release(); //发出完成信号 } } }
/// <summary> /// 对象关闭时登记 /// </summary> public static void OnObjectClose(IZeroObject obj) { lock (ActiveObjects) { ActiveObjects.Remove(obj); ZeroTrace.SystemLog(obj.Name, "Closed"); if (ActiveObjects.Count == 0) { ActiveSemaphore.Release(); //发出完成信号 } } }
/// <summary> /// 对象活动时登记 /// </summary> public static void OnGlobalEnd(IZeroObject obj) { lock (GlobalObjects) { GlobalObjects.Remove(obj); ZeroTrace.SystemLog(obj.Name, "GlobalEnd"); if (GlobalObjects.Count == 0) { GlobalSemaphore.Release(); } } }
/// <summary> /// 结束 /// </summary> /// <returns></returns> public bool End() { if (RunTaskCancel == null) { return(false); } RunTaskCancel.Cancel(); _waitToken.Wait(); RunTaskCancel.Dispose(); RunTaskCancel = null; ZeroTrace.SystemLog($"{Config.StationName}(proxy)", "End"); return(true); }
/// <summary> /// 结束 /// </summary> /// <returns></returns> public bool End() { if (RunTaskCancel == null) { return(false); } RunTaskCancel.Cancel(); _waitToken.Wait(); RunTaskCancel.Dispose(); RunTaskCancel = null; ZeroTrace.SystemLog("ConnectionProxy", "End"); return(true); }
private static void station_update(string name, string content) { if (!ZeroApplication.Config.UpdateConfig(name, content, out var config)) { return; } ZeroTrace.SystemLog("station_update", name, content); if (!ZeroApplication.InRun) { return; } ZeroApplication.OnStationStateChanged(config); ZeroApplication.InvokeEvent(ZeroNetEventType.CenterStationUpdate, content, config); }
private static void station_resume(string name) { if (!ZeroApplication.Config.TryGetConfig(name, out var config)) { return; } ZeroTrace.SystemLog("station_resume", name); config.State = ZeroCenterState.Run; if (ZeroApplication.InRun) { ZeroApplication.OnStationStateChanged(config); } ZeroApplication.InvokeEvent(ZeroNetEventType.CenterStationResume, null, config); }
private static void station_stop(string name) { if (!ZeroApplication.Config.TryGetConfig(name, out var config)) { return; } ZeroTrace.SystemLog("station_stop", name); if (config.State < ZeroCenterState.Stop) { config.State = ZeroCenterState.Stop; } if (!ZeroApplication.InRun) { return; } ZeroApplication.OnStationStateChanged(config); ZeroApplication.InvokeEvent(ZeroNetEventType.CenterStationLeft, null, config); }
/// <summary> /// 刷新配置 /// </summary> /// <param name="json"></param> public bool FlushConfigs(string json) { try { var configs = JsonConvert.DeserializeObject <List <StationConfig> >(json); foreach (var config in configs) { AddStation(config); } ZeroTrace.SystemLog("LoadAllConfig", json); return(true); } catch (Exception e) { ZeroTrace.WriteException("LoadAllConfig", e, json); return(false); } }
/// <summary> /// 注销时调用 /// </summary> internal static void OnZeroDestory() { if (!Monitor.TryEnter(ZeroObjects)) { return; } ZeroTrace.SystemLog("[OnZeroDestory>>"); RaiseEvent(ZeroNetEventType.AppEnd); using (OnceScope.CreateScope(ZeroObjects)) { var array = ZeroObjects.Values.ToArray(); ZeroObjects.Clear(); Parallel.ForEach(array, obj => { try { ZeroTrace.SystemLog(obj.Name, "*Destory"); obj.OnZeroDestory(); } catch (Exception e) { ZeroTrace.WriteException(obj.Name, e, "*Destory"); } }); GC.Collect(); ZeroTrace.SystemLog("<<OnZeroDestory]"); ZeroTrace.SystemLog("[OnZeroDispose>>"); Parallel.ForEach(array, obj => { try { ZeroTrace.SystemLog(obj.Name, "*Dispose"); obj.Dispose(); } catch (Exception e) { ZeroTrace.WriteException(obj.Name, e, "*Dispose"); } }); ZeroTrace.SystemLog("<<OnZeroDispose]"); } }
/// <summary> /// 命令行方式管理 /// </summary> public static void CommandConsole() { while (true) { var cmd = Console.ReadLine(); if (String.IsNullOrWhiteSpace(cmd)) { continue; } switch (cmd.Trim().ToLower()) { case "quit": case "exit": Shutdown(); return; case "start": Start(); continue; } var words = cmd.Split(' ', '\t', '\r', '\n'); if (words.Length == 0) { Console.WriteLine("请输入正确命令"); continue; } var result = SystemManager.Instance.CallCommand(words); if (result.InteractiveSuccess) { ZeroTrace.SystemLog("Console", result.TryGetValue(ZeroFrameType.Status, out var value) ? value : result.State.Text()); } else { ZeroTrace.WriteError("Console", result.TryGetValue(ZeroFrameType.Status, out var value) ? value : result.State.Text()); } } }
/// <summary> /// 注册对象 /// </summary> public static bool RegistZeroObject(IZeroObject obj) { if (obj.GetType().IsSubclassOf(typeof(ApiStation))) { ZeroDiscover.DiscoverApiDocument(obj.GetType()); } using (OnceScope.CreateScope(ZeroObjects)) { if (ZeroObjects.ContainsKey(obj.Name)) { return(false); } ZeroTrace.SystemLog("RegistZeroObject", obj.Name); ZeroObjects.Add(obj.Name, obj); if (ApplicationState >= StationState.Initialized) { try { obj.OnZeroInitialize(); ZeroTrace.SystemLog(obj.Name, "Initialize"); } catch (Exception e) { ZeroTrace.WriteException(obj.Name, e, "Initialize"); } } if (!CanDo) { return(true); } try { ZeroTrace.SystemLog(obj.Name, "Start"); obj.OnZeroStart(); } catch (Exception e) { ZeroTrace.WriteException(obj.Name, e, "Start"); } } return(true); }
/// <summary> /// 系统启动时调用 /// </summary> internal static void OnStationStateChanged(StationConfig config) { using (OnceScope.CreateScope(ZeroObjects)) { ZeroTrace.SystemLog($"[OnStationStateChanged({config.StationName})>>"); Parallel.ForEach(ActiveObjects.Where(p => string.Equals(config.StationName, p.StationName, StringComparison.OrdinalIgnoreCase)).ToArray(), obj => { try { obj.OnStationStateChanged(config); } catch (Exception e) { ZeroTrace.WriteException(obj.Name, e, "OnStationStateChanged"); } }); ZeroTrace.SystemLog($"<<OnStationStateChanged({config.StationName})]"); } }
/// <summary> /// 系统启动时调用 /// </summary> internal static void OnZeroInitialize() { using (OnceScope.CreateScope(ZeroObjects)) { ZeroTrace.SystemLog("[OnZeroInitialize>>"); Parallel.ForEach(ZeroObjects.Values.ToArray(), obj => { try { obj.OnZeroInitialize(); ZeroTrace.SystemLog(obj.Name, "Initialize"); } catch (Exception e) { ZeroTrace.WriteException(obj.Name, e, "*Initialize"); } }); ZeroTrace.SystemLog("<<OnZeroInitialize]"); } }
/// <summary> /// 命令轮询 /// </summary> /// <returns></returns> private void Run() { var configs = ZeroApplication.Config.GetConfigs(p => p.StationType != ZeroStationType.Dispatcher); ZSocket[] sockets = new ZSocket[configs.Length * 2]; int idx = 0; foreach (var config in configs) { sockets[idx++] = ZSocket.CreateServiceSocket($"inproc://{config.StationName}_Proxy", ZSocketType.ROUTER); sockets[idx++] = ZSocket.CreateClientSocket(config.RequestAddress, ZSocketType.DEALER); } WaitCount = 0; ZeroTrace.SystemLog("ConnectionProxy", "Listen"); using (var pool = ZmqPool.CreateZmqPool()) { pool.Prepare(sockets, ZPollEvent.In); _waitToken.Release(); //SystemManager.Instance.HeartReady(StationName, RealName); while (!RunTaskCancel.Token.IsCancellationRequested) { if (!pool.Poll()) { continue; } Parallel.For(0, configs.Length, index => { CheckCall(pool, index * 2); CheckResult(pool, index * 2 + 1); }); } } _waitToken.Release(); }
/// <summary> /// 配置校验 /// </summary> private static void CheckConfig() { var curPath = ConfigurationManager.Root.GetValue("contentRoot", Environment.CurrentDirectory); string rootPath; if (ConfigurationManager.Root["ASPNETCORE_ENVIRONMENT_"] == "Development") { ZeroTrace.SystemLog("Option", "Development"); AppName = ConfigurationManager.Root["AppName"]; rootPath = curPath; } else { ZeroTrace.SystemLog("Option", RuntimeInformation.IsOSPlatform(OSPlatform.Linux) ? "Linux" : "Windows"); rootPath = Path.GetDirectoryName(curPath); AppName = Path.GetFileName(curPath); // ReSharper disable once AssignNullToNotNullAttribute var file = Path.Combine(rootPath, "config", "zero.json"); if (File.Exists(file)) { ConfigurationManager.Load(file); } file = Path.Combine(rootPath, "config", $"{AppName}.json"); if (File.Exists(file)) { ConfigurationManager.Load(file); } var name = ConfigurationManager.Root["AppName"]; if (name == null) { ConfigurationManager.Root["AppName"] = AppName; } else { AppName = name; } } ConfigurationManager.Root["rootPath"] = rootPath; var sec = ConfigurationManager.Get("Zero"); if (sec == null) { throw new Exception("无法找到主配置节点,路径为Zero,在appsettings.json中设置"); } var global = sec.Child <ZeroAppConfig>("Global"); if (global == null) { throw new Exception("无法找到主配置节点,路径为Zero.Global,在appsettings.json中设置"); } Config = string.IsNullOrWhiteSpace(AppName) ? sec.Child <ZeroAppConfig>("Station") : sec.Child <ZeroAppConfig>(AppName) ?? sec.Child <ZeroAppConfig>("Station"); if (Config == null) { throw new Exception($"无法找到主配置节点,路径为Zero.{AppName}或Zero.Station,在appsettings.json中设置"); } Config.BinPath = curPath; Config.RootPath = rootPath; var socketOption = sec.Child <SocketOption>("socketOption"); if (socketOption != null) { ZSocket.Option = socketOption; } if (string.IsNullOrWhiteSpace(AppName)) { ConfigurationManager.Root["AppName"] = AppName = Config.StationName; } Config.IsLinux = RuntimeInformation.IsOSPlatform(OSPlatform.Linux); global.LogFolder = string.IsNullOrWhiteSpace(global.LogFolder) ? IOHelper.CheckPath(rootPath, "logs") : global.LogFolder.Trim(); global.DataFolder = string.IsNullOrWhiteSpace(global.DataFolder) ? IOHelper.CheckPath(rootPath, "datas") : global.DataFolder.Trim(); global.ServiceName = string.IsNullOrWhiteSpace(global.ServiceName) ? Dns.GetHostName() : global.ServiceName.Trim(); global.ServiceKey = string.IsNullOrWhiteSpace(global.ServiceKey) ? RandomOperate.Generate(8) : global.ServiceKey.Trim(); global.ConfigFolder = string.IsNullOrWhiteSpace(global.ConfigFolder) ? IOHelper.CheckPath(rootPath, "config") : global.ConfigFolder.Trim(); global.ZeroAddress = string.IsNullOrWhiteSpace(global.ZeroAddress) ? "127.0.0.1" : global.ZeroAddress.Trim(); if (global.ZeroManagePort <= 1024 || Config.ZeroManagePort >= 65000) { global.ZeroManagePort = 8000; } if (global.ZeroMonitorPort <= 1024 || Config.ZeroMonitorPort >= 65000) { global.ZeroMonitorPort = 8001; } if (global.StationIsolate || Config.StationIsolate) { Config.ServiceName = string.IsNullOrWhiteSpace(Config.ServiceName) ? global.ServiceName : Config.ServiceName.Trim(); Config.ServiceKey = string.IsNullOrWhiteSpace(Config.ServiceKey) ? global.ServiceKey : Config.ServiceKey.Trim(); Config.ZeroAddress = string.IsNullOrWhiteSpace(Config.ZeroAddress) ? global.ZeroAddress : Config.ZeroAddress.Trim(); if (Config.ZeroManagePort <= 1024 || Config.ZeroManagePort >= 65000) { Config.ZeroManagePort = global.ZeroManagePort; } if (Config.ZeroMonitorPort <= 1024 || Config.ZeroMonitorPort >= 65000) { Config.ZeroMonitorPort = global.ZeroMonitorPort; } Config.DataFolder = string.IsNullOrWhiteSpace(Config.DataFolder) ? global.DataFolder : IOHelper.CheckPath(global.DataFolder, AppName, "datas"); Config.LogFolder = string.IsNullOrWhiteSpace(Config.LogFolder) ? global.LogFolder : IOHelper.CheckPath(global.LogFolder, AppName, "logs"); Config.ConfigFolder = string.IsNullOrWhiteSpace(Config.ConfigFolder) ? global.ConfigFolder : IOHelper.CheckPath(rootPath, AppName, "config"); } else { Config.ServiceName = global.ServiceName; Config.ServiceKey = global.ServiceKey; Config.ZeroAddress = global.ZeroAddress; Config.ZeroManagePort = global.ZeroManagePort; Config.ZeroMonitorPort = global.ZeroMonitorPort; Config.DataFolder = global.DataFolder; Config.LogFolder = global.LogFolder; Config.ConfigFolder = global.ConfigFolder; } TxtRecorder.LogPath = Config.LogFolder; ConfigurationManager.Get("LogRecorder")["txtPath"] = Config.LogFolder; Config.ZeroManageAddress = ZeroIdentityHelper.GetRequestAddress("SystemManage", Config.ZeroManagePort); Config.ZeroMonitorAddress = ZeroIdentityHelper.GetWorkerAddress("SystemMonitor", Config.ZeroMonitorPort); Config.LocalIpAddress = GetHostIps(); Config.ShortName = string.IsNullOrWhiteSpace(Config.ShortName) ? Config.StationName : Config.ShortName.Trim(); Config.RealName = ZeroIdentityHelper.CreateRealName(false); Config.Identity = Config.RealName.ToAsciiBytes(); //模式选择 if (Config.SpeedLimitModel < SpeedLimitType.Single || Config.SpeedLimitModel > SpeedLimitType.WaitCount) { Config.SpeedLimitModel = SpeedLimitType.ThreadCount; } if (Config.TaskCpuMultiple <= 0) { Config.TaskCpuMultiple = 1; } else if (Config.TaskCpuMultiple > 128) { Config.TaskCpuMultiple = 128; } if (Config.MaxWait < 0xFF) { Config.MaxWait = 0xFF; } else if (Config.MaxWait > 0xFFFFF) { Config.MaxWait = 0xFFFFF; } ShowOptionInfo(rootPath); }