/// <summary> /// 站点心跳 /// </summary> /// <param name="name"></param> /// <param name="content"></param> private static void station_state(string name, string content) { //ZeroTrace.WriteInfo("station_state",name); if (!ZeroApplication.Config.TryGetConfig(name, out var config)) { return; } try { ZeroApplication.InvokeEvent(ZeroNetEventType.CenterStationState, content, config); } catch (Exception e) { LogRecorder.Exception(e); ZeroTrace.WriteException("station_state", e, name, content); } }
/// <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); } }
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); }
private static void station_left(string name) { if (!ZeroApplication.Config.TryGetConfig(name, out var config)) { return; } ZeroTrace.WriteInfo("station_left", name); if (config.State < ZeroCenterState.Closed) { config.State = ZeroCenterState.Closed; } if (!ZeroApplication.InRun) { return; } ZeroApplication.OnStationStateChanged(config); ZeroApplication.InvokeEvent(ZeroNetEventType.CenterStationLeft, null, config); }
/// <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> internal static void OnStationStateChanged(StationConfig config) { using (OnceScope.CreateScope(ZeroObjects)) { ZeroTrace.WriteLine("[OnStationStateChanged>>"); Parallel.ForEach(ActiveObjects.ToArray(), obj => { try { obj.OnStationStateChanged(config); } catch (Exception e) { ZeroTrace.WriteException(obj.Name, e, "OnStationStateChanged"); } }); ZeroTrace.WriteLine("<<OnStationStateChanged]"); } }
/// <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]"); } }
private void CheckResult(IZmqPool pool, int idx) { if (!pool.CheckIn(idx, out var message)) { return; } try { using (message) { using (ZMessage clone = new ZMessage()) { byte[] des = message[0].Read(); int size = des[0] + 2; for (var index = 2; index < size && index < des.Length; index++) { if (des[index] != ZeroFrameType.Requester) { continue; } clone.Add(message[index - 1].Duplicate()); break; } //clone.Add(new ZFrame("".ToAsciiBytes())); clone.Add(new ZFrame(des)); for (var index = 1; index < message.Count; index++) { clone.Add(message[index].Duplicate()); } pool.Sockets[idx - 1].SendMessage(clone, out _); --WaitCount; } } } catch (Exception e) { ZeroTrace.WriteException("ConnectionProxy", e, "CheckResult"); } }
/// <summary> /// 试着取配置 /// </summary> /// <param name="stationName"></param> /// <param name="json"></param> /// <param name="config"></param> /// <returns></returns> public bool UpdateConfig(string stationName, string json, out StationConfig config) { if (stationName == null || string.IsNullOrEmpty(json) || json[0] != '{') { ZeroTrace.WriteError("UpdateConfig", "argument error", stationName, json); config = null; return(false); } try { config = JsonConvert.DeserializeObject <StationConfig>(json); AddStation(config); return(true); } catch (Exception e) { ZeroTrace.WriteException("UpdateConfig", e, stationName, json); config = null; return(false); } }
/// <summary> /// 系统启动时调用 /// </summary> internal static void OnZeroStart() { Debug.Assert(!HaseActiveObject); using (OnceScope.CreateScope(ZeroObjects, ResetObjectActive)) { ZeroTrace.WriteLine("[OnZeroStart>>"); #if DEBUG foreach (var obj in ZeroObjects.Values.ToArray()) { try { ZeroTrace.WriteInfo(obj.Name, "*Start"); obj.OnZeroStart(); } catch (Exception e) { ZeroTrace.WriteException(obj.Name, e, "*Start"); } } #else Parallel.ForEach(ZeroObjects.Values.ToArray(), obj => { try { ZeroTrace.WriteInfo(obj.Name, "*Start"); obj.OnZeroStart(); } catch (Exception e) { ZeroTrace.WriteException(obj.Name, e, "*Start"); } }); #endif WaitAllObjectSemaphore(); } SystemManager.Instance.HeartReady(); ApplicationState = StationState.Run; RaiseEvent(ZeroNetEventType.AppRun); ZeroTrace.WriteLine("<<OnZeroStart]"); }
/// <summary> /// 下载文档 /// </summary> /// <returns></returns> public bool LoadDocument(string name, out StationDocument doc) { ZeroResultData result; try { result = CallCommand("doc", name); if (!result.InteractiveSuccess || result.State != ZeroOperatorStateType.Ok) { ZeroTrace.WriteError("LoadDocument", result); doc = null; return(false); } } catch (Exception e) { ZeroTrace.WriteException("LoadDocument", e); doc = null; return(false); } if (!result.TryGetValue(ZeroFrameType.Status, out var json)) { ZeroTrace.WriteError("LoadDocument", "Empty"); doc = null; return(false); } try { doc = JsonConvert.DeserializeObject <StationDocument>(json); return(true); } catch (Exception e) { ZeroTrace.WriteException("LoadDocument", e, json); doc = null; return(false); } }
/// <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> /// <returns></returns> public bool UploadDocument() { if (DocumentIsUpload) { return(true); } bool success = true; foreach (var doc in ZeroApplication.Config.Documents.Values) { if (!doc.IsLocal) { continue; } var result = CallCommand("doc", doc.Name, JsonConvert.SerializeObject(doc)); if (!result.InteractiveSuccess || result.State != ZeroOperatorStateType.Ok) { ZeroTrace.WriteError("UploadDocument", result); success = false; } } DocumentIsUpload = success; return(success); }
/// <summary> /// 接收字节 /// </summary> /// <param name="socket"></param> /// <returns></returns> public static ZeroResultData <byte[]> Receive(this ZSocket socket) { ZMessage messages; try { if (!socket.Recv(out messages)) { return(new ZeroResultData <byte[]> { State = ZeroOperatorStateType.LocalRecvError, ZmqError = socket.LastError }); } } catch (Exception e) { ZeroTrace.WriteException("Receive", e, socket.Connects.LinkToString(','), "Exception"); return(new ZeroResultData <byte[]> { State = ZeroOperatorStateType.LocalRecvError, Exception = e }); } try { var description = messages[0].Read(); if (description.Length < 2) { ZeroTrace.WriteError("Receive", "LaoutError", socket.Connects.LinkToString(','), description.LinkToString(p => p.ToString("X2"), "")); return(new ZeroResultData <byte[]> { State = ZeroOperatorStateType.FrameInvalid, Message = "网络格式错误" }); } int end = description[0] + 1; if (end != messages.Count) { ZeroTrace.WriteError("Receive", "LaoutError", socket.Connects.LinkToString(','), $"FrameSize{messages.Count}", description.LinkToString(p => p.ToString("X2"), "")); return(new ZeroResultData <byte[]> { State = ZeroOperatorStateType.FrameInvalid, Message = "网络格式错误" }); } var result = new ZeroResultData <byte[]> { InteractiveSuccess = true, State = (ZeroOperatorStateType)description[1] }; for (int idx = 1; idx < end; idx++) { result.Add(description[idx + 1], messages[idx].Read()); } return(result); } catch (Exception e) { ZeroTrace.WriteException("Receive", e, socket.Connects.LinkToString(','), $"FrameSize{messages.Count},Socket Ptr:{ socket.SocketPtr}."); return(new ZeroResultData <byte[]> { State = ZeroOperatorStateType.LocalRecvError, Exception = e }); } finally { messages.Dispose(); } }
/// <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); }
/// <summary> /// 广播消息解包 /// </summary> /// <param name="messages"></param> /// <param name="item"></param> /// <param name="showError"></param> /// <returns></returns> public static bool Unpack(this ZMessage messages, out PublishItem item, bool showError = true) { if (messages == null) { item = null; return(false); } try { if (messages.Count < 3) { item = null; return(false); } var description = messages[1].Read(); if (description.Length < 2) { item = null; return(false); } int end = description[0] + 2; if (end != messages.Count) { item = null; return(false); } item = new PublishItem { Title = messages[0].ReadString(), State = (ZeroOperatorStateType)description[1], ZeroEvent = (ZeroNetEventType)description[1] }; for (int idx = 2; idx < end; idx++) { var bytes = messages[idx].Read(); if (bytes.Length == 0) { continue; } switch (description[idx]) { case ZeroFrameType.SubTitle: item.SubTitle = Encoding.UTF8.GetString(bytes); break; case ZeroFrameType.Station: item.Station = Encoding.UTF8.GetString(bytes); break; case ZeroFrameType.Publisher: item.Publisher = Encoding.UTF8.GetString(bytes); break; case ZeroFrameType.Content: if (item.Content == null) { item.Content = Encoding.UTF8.GetString(bytes); } else { item.Values.Add(Encoding.UTF8.GetString(bytes)); } break; case ZeroFrameType.BinaryValue: item.Buffer = bytes; break; case ZeroFrameType.TsonValue: item.Tson = bytes; break; default: item.Values.Add(Encoding.UTF8.GetString(bytes)); break; } } return(true); } catch (Exception e) { ZeroTrace.WriteException("Unpack", e); item = null; return(false); } finally { messages.Dispose(); } }