public WsServerNodeAddressSet() { VirtualRoot.AddOnecePath <WebSocketServerStatedEvent>("WebSocket服务启动后上报节点信息,获取节点列表", LogEnum.UserConsole, action: _ => { ReportNodeAsync(callback: () => { RefreshNodes(callback: () => { NTMinerConsole.UserOk("Ws服务器节点地址集初始化完成"); VirtualRoot.RaiseEvent(new WsServerNodeAddressSetInitedEvent()); }); }); VirtualRoot.AddEventPath <Per10SecondEvent>("节点呼吸", LogEnum.UserConsole, action: message => { ReportNodeAsync(); }, this.GetType()); VirtualRoot.AddEventPath <Per1MinuteEvent>("敲响打扫时间到的铃声", LogEnum.UserConsole, action: message => { RefreshNodes(); }, typeof(WsRoot)); // 收到Mq消息之前一定已经初始化完成,因为Mq消费者在WsServerNodeAddressSetInitedEvent事件之后才会创建 VirtualRoot.AddEventPath <WsServerNodeRemovedMqMessage>("收到移除了服务器节点Mq消息后敲响打扫时间到的铃声", LogEnum.UserConsole, action: message => { if (message.WsServerAddress == ServerRoot.HostConfig.ThisServerAddress) { return; } RefreshNodes(); }, typeof(WsRoot)); VirtualRoot.AddEventPath <WsServerNodeAddedMqMessage>("收到添加了服务器节点Mq消息后敲响打扫时间到的铃声", LogEnum.UserConsole, action: message => { if (message.WsServerAddress == ServerRoot.HostConfig.ThisServerAddress) { return; } RefreshNodes(); }, typeof(WsRoot)); }, PathId.Empty, this.GetType()); }
private void ReportNodeAsync(Action callback = null) { int minerClientWsSessionCount = 0; int minerStudioWsSessionCount = 0; minerClientWsSessionCount = WsRoot.MinerClientSessionSet.WsSessionManager.Count; minerStudioWsSessionCount = WsRoot.MinerStudioSessionSet.WsSessionManager.Count; var ram = Windows.Ram.Instance; var cpu = Windows.Cpu.Instance; RpcRoot.OfficialServer.WsServerNodeService.ReportNodeStateAsync(new WsServerNodeState { Address = ServerRoot.HostConfig.ThisServerAddress, Description = string.Empty, MinerClientSessionCount = WsRoot.MinerClientSessionSet.Count, MinerStudioSessionCount = WsRoot.MinerStudioSessionSet.Count, MinerClientWsSessionCount = minerClientWsSessionCount, MinerStudioWsSessionCount = minerStudioWsSessionCount, Cpu = cpu.ToData(), TotalPhysicalMemory = ram.TotalPhysicalMemory, AvailablePhysicalMemory = ram.AvailablePhysicalMemory, OSInfo = Windows.OS.Instance.OsInfo, CpuPerformance = cpu.GetCurrentCpuUsage() }, (response, e) => { if (response.IsSuccess()) { NTMinerConsole.UserOk("呼吸成功"); } else { NTMinerConsole.UserFail("呼吸失败:" + response.ReadMessage(e)); } callback?.Invoke(); }); }
public UserSet(IUserDataRedis redis, IUserMqSender mqSender) : base(redis) { _redis = redis; _mqSender = mqSender; VirtualRoot.BuildCmdPath <UpdateUserRSAKeyMqCommand>(path: message => { if (message.AppId == ServerRoot.HostConfig.ThisServerAddress) { return; } if (string.IsNullOrEmpty(message.LoginName)) { return; } if (IsOldMqMessage(message.Timestamp)) { NTMinerConsole.UserOk(nameof(UpdateUserRSAKeyMqCommand) + ":" + MqKeyword.SafeIgnoreMessage); return; } if (message.Key != null && _dicByLoginName.TryGetValue(message.LoginName, out UserData userData)) { userData.Update(message.Key); redis.SetAsync(userData).ContinueWith(t => { _mqSender.SendUserRSAKeyUpdated(message.LoginName); }); } }, this.GetType(), LogEnum.DevConsole); }
protected override void Build(IModel channal) { channal.QueueBind(queue: Queue, exchange: MqKeyword.NTMinerExchange, routingKey: MqKeyword.WsServerNodeAddedRoutingKey, arguments: null); channal.QueueBind(queue: Queue, exchange: MqKeyword.NTMinerExchange, routingKey: MqKeyword.WsServerNodeRemovedRoutingKey, arguments: null); NTMinerConsole.UserOk("WsServerNodeMq QueueBind成功"); }
private void CreateProcessAsync() { Task.Factory.StartNew(() => { lock (_locker) { try { // 清理除当前外的Temp/Kernel Cleaner.Instance.Clear(); NTMinerConsole.UserOk("场地打扫完毕"); // 应用超频 if (NTMinerContext.Instance.GpuProfileSet.IsOverClockEnabled(MainCoin.GetId())) { NTMinerConsole.UserWarn("应用超频,如果CPU性能较差耗时可能超过1分钟,请耐心等待"); var cmd = new CoinOverClockCommand(coinId: MainCoin.GetId()); AddOnecePath <CoinOverClockDoneEvent>("超频完成后继续流程", LogEnum.DevConsole, message => { // pathId是唯一的,从而可以断定该消息一定是因为该命令而引发的 ContinueCreateProcess(); }, location: this.GetType(), pathId: cmd.MessageId); // 超频是在另一个线程执行的,因为N卡超频当cpu性能非常差时较耗时 VirtualRoot.Execute(cmd); } else { ContinueCreateProcess(); } } catch (Exception e) { Logger.ErrorDebugLine(e); NTMinerConsole.UserFail("挖矿内核启动失败,请联系开发人员解决"); } } }); }
protected override void Build(IModel channal) { channal.QueueBind(queue: Queue, exchange: MqKeyword.NTMinerExchange, routingKey: MqKeyword.MinerClientWsClosedRoutingKey, arguments: null); channal.QueueBind(queue: Queue, exchange: MqKeyword.NTMinerExchange, routingKey: MqKeyword.MinerClientsWsBreathedRoutingKey, arguments: null); NTMinerConsole.UserOk("WsBreathedMq QueueBind成功"); }
private void OverClock(INTMinerContext root, IGpuProfile data) { #if DEBUG NTStopwatch.Start(); #endif if (root.GpuSet.TryGetGpu(data.Index, out IGpu gpu)) { // fanSpeed == -1表示开源自动温控 int fanSpeed = data.IsAutoFanSpeed ? -1 : data.Cool; root.GpuSet.OverClock.OverClock(data.Index, data.CoreClockDelta, data.CoreVoltage, data.MemoryClockDelta, data.MemoryVoltage, data.PowerCapacity, data.TempLimit, fanSpeed); if (data.Index == NTMinerContext.GpuAllId) { NTMinerConsole.UserOk($"统一超频:{data.ToOverClockString()}"); } else { NTMinerConsole.UserOk($"GPU{gpu.Index}超频:{data.ToOverClockString()}"); } 2.SecondsDelay().ContinueWith(t => { root.GpuSet.OverClock.RefreshGpuState(data.Index); }); } #if DEBUG var elapsedMilliseconds = NTStopwatch.Stop(); if (elapsedMilliseconds.ElapsedMilliseconds > NTStopwatch.ElapsedMilliseconds) { NTMinerConsole.DevTimeSpan($"耗时{elapsedMilliseconds} {this.GetType().Name}.{nameof(OverClock)}"); } #endif }
protected override void Build(IModel channal) { channal.QueueBind(queue: Queue, exchange: MqKeyword.NTMinerExchange, routingKey: WsMqKeyword.GetConsoleOutLinesRoutingKey, arguments: null); channal.QueueBind(queue: Queue, exchange: MqKeyword.NTMinerExchange, routingKey: WsMqKeyword.ConsoleOutLinesRoutingKey, arguments: null); channal.QueueBind(queue: Queue, exchange: MqKeyword.NTMinerExchange, routingKey: WsMqKeyword.GetLocalMessagesRoutingKey, arguments: null); channal.QueueBind(queue: Queue, exchange: MqKeyword.NTMinerExchange, routingKey: WsMqKeyword.LocalMessagesRoutingKey, arguments: null); channal.QueueBind(queue: Queue, exchange: MqKeyword.NTMinerExchange, routingKey: WsMqKeyword.GetDrivesRoutingKey, arguments: null); channal.QueueBind(queue: Queue, exchange: MqKeyword.NTMinerExchange, routingKey: WsMqKeyword.DrivesRoutingKey, arguments: null); channal.QueueBind(queue: Queue, exchange: MqKeyword.NTMinerExchange, routingKey: WsMqKeyword.SetVirtualMemoryRoutingKey, arguments: null); channal.QueueBind(queue: Queue, exchange: MqKeyword.NTMinerExchange, routingKey: WsMqKeyword.GetLocalIpsRoutingKey, arguments: null); channal.QueueBind(queue: Queue, exchange: MqKeyword.NTMinerExchange, routingKey: WsMqKeyword.SetLocalIpsRoutingKey, arguments: null); channal.QueueBind(queue: Queue, exchange: MqKeyword.NTMinerExchange, routingKey: WsMqKeyword.LocalIpsRoutingKey, arguments: null); channal.QueueBind(queue: Queue, exchange: MqKeyword.NTMinerExchange, routingKey: WsMqKeyword.GetOperationResultsRoutingKey, arguments: null); channal.QueueBind(queue: Queue, exchange: MqKeyword.NTMinerExchange, routingKey: WsMqKeyword.OperationResultsRoutingKey, arguments: null); channal.QueueBind(queue: Queue, exchange: MqKeyword.NTMinerExchange, routingKey: WsMqKeyword.OperationReceivedRoutingKey, arguments: null); channal.QueueBind(queue: Queue, exchange: MqKeyword.NTMinerExchange, routingKey: WsMqKeyword.GetSpeedRoutingKey, arguments: null); channal.QueueBind(queue: Queue, exchange: MqKeyword.NTMinerExchange, routingKey: WsMqKeyword.SwitchRadeonGpuRoutingKey, arguments: null); channal.QueueBind(queue: Queue, exchange: MqKeyword.NTMinerExchange, routingKey: WsMqKeyword.GetSelfWorkLocalJsonRoutingKey, arguments: null); channal.QueueBind(queue: Queue, exchange: MqKeyword.NTMinerExchange, routingKey: WsMqKeyword.SelfWorkLocalJsonRoutingKey, arguments: null); channal.QueueBind(queue: Queue, exchange: MqKeyword.NTMinerExchange, routingKey: WsMqKeyword.SaveSelfWorkLocalJsonRoutingKey, arguments: null); channal.QueueBind(queue: Queue, exchange: MqKeyword.NTMinerExchange, routingKey: WsMqKeyword.GetGpuProfilesJsonRoutingKey, arguments: null); channal.QueueBind(queue: Queue, exchange: MqKeyword.NTMinerExchange, routingKey: WsMqKeyword.GpuProfilesJsonRoutingKey, arguments: null); channal.QueueBind(queue: Queue, exchange: MqKeyword.NTMinerExchange, routingKey: WsMqKeyword.SaveGpuProfilesJsonRoutingKey, arguments: null); channal.QueueBind(queue: Queue, exchange: MqKeyword.NTMinerExchange, routingKey: WsMqKeyword.UpgradeNTMinerRoutingKey, arguments: null); channal.QueueBind(queue: Queue, exchange: MqKeyword.NTMinerExchange, routingKey: WsMqKeyword.StartMineRoutingKey, arguments: null); channal.QueueBind(queue: Queue, exchange: MqKeyword.NTMinerExchange, routingKey: WsMqKeyword.StopMineRoutingKey, arguments: null); NTMinerConsole.UserOk("OperationMq QueueBind成功"); }
private void OverClock(INTMinerContext ntminerContext, IGpuProfile data) { #if DEBUG NTStopwatch.Start(); #endif if (ntminerContext.GpuSet.TryGetGpu(data.Index, out IGpu gpu)) { ntminerContext.GpuSet.OverClock.OverClock(gpuIndex: data.Index, OverClockValue.Create(data)); if (data.Index == NTMinerContext.GpuAllId) { NTMinerConsole.UserOk($"统一超频:{data.ToOverClockString()}"); } else { NTMinerConsole.UserOk($"GPU{gpu.Index}超频:{data.ToOverClockString()}"); } 2.SecondsDelay().ContinueWith(t => { ntminerContext.GpuSet.OverClock.RefreshGpuState(data.Index); }); } #if DEBUG var elapsedMilliseconds = NTStopwatch.Stop(); if (elapsedMilliseconds.ElapsedMilliseconds > NTStopwatch.ElapsedMilliseconds) { NTMinerConsole.DevTimeSpan($"耗时{elapsedMilliseconds} {this.GetType().Name}.{nameof(OverClock)}"); } #endif }
protected override void Build(IModel channal) { channal.QueueBind(queue: Queue, exchange: MqKeyword.NTMinerExchange, routingKey: MqKeyword.SpeedsRoutingKey, arguments: null); channal.QueueBind(queue: Queue, exchange: MqKeyword.NTMinerExchange, routingKey: MqKeyword.ChangeMinerSignRoutingKey, arguments: null); channal.QueueBind(queue: Queue, exchange: MqKeyword.NTMinerExchange, routingKey: MqKeyword.QueryClientsForWsRoutingKey, arguments: null); NTMinerConsole.UserOk("MinerClientMq QueueBind成功"); }
protected override void Build(IModel channal) { channal.QueueBind(queue: Queue, exchange: MqKeyword.NTMinerExchange, routingKey: MqKeyword.MinerDataAddedRoutingKey, arguments: null); channal.QueueBind(queue: Queue, exchange: MqKeyword.NTMinerExchange, routingKey: MqKeyword.MinerDataRemovedRoutingKey, arguments: null); channal.QueueBind(queue: Queue, exchange: MqKeyword.NTMinerExchange, routingKey: MqKeyword.MinerSignChangedRoutingKey, arguments: null); NTMinerConsole.UserOk("MinerSignMq QueueBind成功"); }
protected internal override void Build(IModel channel) { DoBuild(channel); channel.QueueBind(queue: Queue, exchange: MqKeyword.NTMinerExchange, routingKey: MqKeyword.UserAddedRoutingKey, arguments: null); channel.QueueBind(queue: Queue, exchange: MqKeyword.NTMinerExchange, routingKey: MqKeyword.UserUpdatedRoutingKey, arguments: null); channel.QueueBind(queue: Queue, exchange: MqKeyword.NTMinerExchange, routingKey: MqKeyword.UserRemovedRoutingKey, arguments: null); channel.QueueBind(queue: Queue, exchange: MqKeyword.NTMinerExchange, routingKey: MqKeyword.UserEnabledRoutingKey, arguments: null); channel.QueueBind(queue: Queue, exchange: MqKeyword.NTMinerExchange, routingKey: MqKeyword.UserDisabledRoutingKey, arguments: null); channel.QueueBind(queue: Queue, exchange: MqKeyword.NTMinerExchange, routingKey: MqKeyword.UserPasswordChangedRoutingKey, arguments: null); channel.QueueBind(queue: Queue, exchange: MqKeyword.NTMinerExchange, routingKey: MqKeyword.UserRSAKeyUpdatedRoutingKey, arguments: null); NTMinerConsole.UserOk("UserMq QueueBind成功"); }
private void ContinueCreateProcess() { Thread.Sleep(1000); if (this != NTMinerContext.Instance.LockedMineContext) { NTMinerConsole.UserWarn("结束开始挖矿"); return; } // 执行文件书写器 this.ExecuteFileWriters(); // 分离命令名和参数 GetCmdNameAndArguments(out string kernelExeFileFullName, out string arguments); // 这是不应该发生的,如果发生很可能是填写命令的时候拼写错误了 if (!File.Exists(kernelExeFileFullName)) { NTMinerConsole.UserError(kernelExeFileFullName + "文件不存在,可能是被杀软删除导致,请退出杀毒软件重试或者QQ群联系小编,解释:大部分挖矿内核会报毒,不是开源矿工的问题也不是杀软的问题,也不是挖矿内核的问题,是挖矿这件事情的问题,可能是挖矿符合了病毒的定义。"); } if (this.KernelProcessType == KernelProcessType.Logfile) { arguments = arguments.Replace(NTKeyword.LogFileParameterName, this.LogFileFullName); } NTMinerConsole.UserOk($"\"{kernelExeFileFullName}\" {arguments}"); NTMinerConsole.UserInfo($"有请内核上场"); if (this != NTMinerContext.Instance.LockedMineContext) { NTMinerConsole.UserWarn("结束开始挖矿"); return; } NTMinerConsole.InitOnece(isForce: true, initHide: !NTMinerContext.IsUiVisible); switch (this.KernelProcessType) { case KernelProcessType.Logfile: CreateLogfileProcess(kernelExeFileFullName, arguments); break; case KernelProcessType.Pip: CreatePipProcess(kernelExeFileFullName, arguments); break; default: throw new InvalidProgramException(); } this.ProcessCreatedOn = DateTime.Now; KernelProcessDaemon(); VirtualRoot.RaiseEvent(new MineStartedEvent(this)); }
public WsServerNodeAddressSet(IWsServerNodeRedis wsServerNodeRedis, IWsServerNodeMqSender wsServerNodeMqSender) : base(wsServerNodeRedis) { _wsServerNodeRedis = wsServerNodeRedis; _wsServerNodeMqSender = wsServerNodeMqSender; VirtualRoot.BuildOnecePath <WebSocketServerStatedEvent>("上报节点信息,获取节点列表", LogEnum.UserConsole, PathId.Empty, this.GetType(), PathPriority.Normal, path: _ => { ReportNodeAsync(callback: () => { base.Init(callback: () => { NTMinerConsole.UserOk("Ws服务器节点地址集初始化完成"); VirtualRoot.RaiseEvent(new WsServerNodeAddressSetInitedEvent()); }); _wsServerNodeMqSender.SendWsServerNodeAdded(); }); VirtualRoot.BuildEventPath <Per10SecondEvent>("节点呼吸", LogEnum.UserConsole, this.GetType(), PathPriority.Normal, path: message => { ReportNodeAsync(); }); }); }
private void ReportNodeAsync(Action callback = null) { Task.Factory.StartNew(() => { WsServerNodeState nodeState = null; try { int minerClientWsSessionCount = 0; int minerStudioWsSessionCount = 0; minerClientWsSessionCount = AppRoot.WsServer.MinerClientWsSessions.Count; minerStudioWsSessionCount = AppRoot.WsServer.MinerStudioWsSessions.Count; var ram = Windows.Ram.Instance; var cpu = Windows.Cpu.Instance; nodeState = new WsServerNodeState { Address = ServerRoot.HostConfig.ThisServerAddress, Description = string.Empty, MinerClientSessionCount = AppRoot.MinerClientSessionSet.Count, MinerStudioSessionCount = AppRoot.MinerStudioSessionSet.Count, MinerClientWsSessionCount = minerClientWsSessionCount, MinerStudioWsSessionCount = minerStudioWsSessionCount, Cpu = cpu.ToData(), TotalPhysicalMemory = ram.TotalPhysicalMemory, AvailablePhysicalMemory = ram.AvailablePhysicalMemory, OSInfo = Windows.OS.Instance.OsInfo, CpuPerformance = cpu.GetTotalCpuUsage(), // 以下三个属性的访问约耗时30毫秒所以放在Task中 ProcessMemoryMb = VirtualRoot.ProcessMemoryMb, ThreadCount = VirtualRoot.ThreadCount, HandleCount = VirtualRoot.HandleCount, AvailableFreeSpaceInfo = VirtualRoot.GetAvailableFreeSpaceInfo() }; } catch (Exception e) { Logger.ErrorDebugLine(e); } _wsServerNodeRedis.SetAsync(nodeState).ContinueWith(t => { if (t.Exception != null) { NTMinerConsole.UserFail("呼吸失败:" + t.Exception.Message); } else { NTMinerConsole.UserOk("呼吸成功"); } callback?.Invoke(); }); }); }
public WsServerNodeAddressSet(IWsServerNodeRedis wsServerNodeRedis, IWsServerNodeMqSender wsServerNodeMqSender) : base(wsServerNodeRedis) { _wsServerNodeRedis = wsServerNodeRedis; _wsServerNodeMqSender = wsServerNodeMqSender; VirtualRoot.BuildOnecePath <WebSocketServerStatedEvent>("WebSocket服务启动后上报节点信息,获取节点列表", LogEnum.UserConsole, path: _ => { ReportNodeAsync(callback: () => { base.Init(callback: () => { NTMinerConsole.UserOk("Ws服务器节点地址集初始化完成"); VirtualRoot.RaiseEvent(new WsServerNodeAddressSetInitedEvent()); }); _wsServerNodeMqSender.SendWsServerNodeAdded(ServerRoot.HostConfig.ThisServerAddress); }); VirtualRoot.BuildEventPath <Per10SecondEvent>("节点呼吸", LogEnum.UserConsole, path: message => { ReportNodeAsync(); }, this.GetType()); VirtualRoot.BuildEventPath <Per1MinuteEvent>("打扫", LogEnum.DevConsole, path: message => { VirtualRoot.RaiseEvent(new CleanTimeArrivedEvent(AsEnumerable().ToArray())); }, this.GetType()); }, PathId.Empty, this.GetType()); }
private void ReportNodeAsync(Action callback = null) { WsServerNodeState nodeState = null; try { int minerClientWsSessionCount = 0; int minerStudioWsSessionCount = 0; minerClientWsSessionCount = WsRoot.MinerClientSessionSet.WsSessionManager.Count; minerStudioWsSessionCount = WsRoot.MinerStudioSessionSet.WsSessionManager.Count; var ram = Windows.Ram.Instance; var cpu = Windows.Cpu.Instance; nodeState = new WsServerNodeState { Address = ServerRoot.HostConfig.ThisServerAddress, Description = string.Empty, MinerClientSessionCount = WsRoot.MinerClientSessionSet.Count, MinerStudioSessionCount = WsRoot.MinerStudioSessionSet.Count, MinerClientWsSessionCount = minerClientWsSessionCount, MinerStudioWsSessionCount = minerStudioWsSessionCount, Cpu = cpu.ToData(), TotalPhysicalMemory = ram.TotalPhysicalMemory, AvailablePhysicalMemory = ram.AvailablePhysicalMemory, OSInfo = Windows.OS.Instance.OsInfo, CpuPerformance = cpu.GetCurrentCpuUsage() }; } catch (Exception e) { Logger.ErrorDebugLine(e); } _wsServerNodeRedis.SetAsync(nodeState).ContinueWith(t => { if (t.Exception != null) { NTMinerConsole.UserFail("呼吸失败:" + t.Exception.Message); } else { NTMinerConsole.UserOk("呼吸成功"); } callback?.Invoke(); }); }
public void ShowSuccess(string message, string header, int autoHideSeconds, bool toConsole = false) { if (toConsole) { NTMinerConsole.UserOk(message); } UIThread.Execute(() => { var builder = NotificationMessageBuilder.CreateMessage(Manager); builder.Success(header, message); if (autoHideSeconds > 0) { builder .Dismiss() .WithDelay(autoHideSeconds) .Queue(); } else { builder .Dismiss().WithButton("知道了", null) .Queue(); } }); }
private void OverClock(INTMinerContext root, IGpuProfile data) { #if DEBUG NTStopwatch.Start(); #endif if (root.GpuSet.TryGetGpu(data.Index, out IGpu gpu)) { IOverClock overClock = root.GpuSet.OverClock; if (!data.IsAutoFanSpeed) { overClock.SetFanSpeed(data.Index, data.Cool); } overClock.SetCoreClock(data.Index, data.CoreClockDelta, data.CoreVoltage); overClock.SetMemoryClock(data.Index, data.MemoryClockDelta, data.MemoryVoltage); overClock.SetPowerLimit(data.Index, data.PowerCapacity); overClock.SetTempLimit(data.Index, data.TempLimit); if (data.Index == NTMinerContext.GpuAllId) { NTMinerConsole.UserOk($"统一超频:{data.ToOverClockString()}"); } else { NTMinerConsole.UserOk($"GPU{gpu.Index}超频:{data.ToOverClockString()}"); } 1.SecondsDelay().ContinueWith(t => { overClock.RefreshGpuState(data.Index); }); } #if DEBUG var elapsedMilliseconds = NTStopwatch.Stop(); if (elapsedMilliseconds.ElapsedMilliseconds > NTStopwatch.ElapsedMilliseconds) { NTMinerConsole.DevTimeSpan($"耗时{elapsedMilliseconds} {this.GetType().Name}.OverClock"); } #endif }
public ClientDataSet(IMinerRedis minerRedis, ISpeedDataRedis speedDataRedis, IMinerClientMqSender mqSender) : base(isPull: false, getDatas: callback => { var getMinersTask = minerRedis.GetAllAsync(); var getSpeedsTask = speedDataRedis.GetAllAsync(); Task.WhenAll(getMinersTask, getSpeedsTask).ContinueWith(t => { NTMinerConsole.UserInfo($"从redis加载了 {getMinersTask.Result.Count} 条MinerData,和 {getSpeedsTask.Result.Count} 条SpeedData"); var speedDatas = getSpeedsTask.Result; List <ClientData> clientDatas = new List <ClientData>(); DateTime speedOn = DateTime.Now.AddMinutes(-3); foreach (var minerData in getMinersTask.Result) { var clientData = ClientData.Create(minerData); // 该属性没有持久化而只在内存中,启动时将该属性值视为当前日期的前一天的零时加上CreatedOn // 的时间从而将数据分散开来从而滑动清理,后面有个周期清理7天不活跃矿机的任务。WebApiServer启动后第6天才会进行第一次清理。 clientData.MinerActiveOn = DateTime.Today.AddDays(-1) + minerData.CreatedOn.TimeOfDay; clientDatas.Add(clientData); var speedData = speedDatas.FirstOrDefault(a => a.ClientId == minerData.ClientId); if (speedData != null && speedData.SpeedOn > speedOn) { clientData.Update(speedData, out bool _); } } callback?.Invoke(clientDatas); }); }) { _minerRedis = minerRedis; _speedDataRedis = speedDataRedis; _mqSender = mqSender; VirtualRoot.BuildEventPath <Per1MinuteEvent>("周期清理Redis中不活跃的来自挖矿端上报的算力记录", LogEnum.DevConsole, path: message => { DateTime time = message.BornOn.AddSeconds(-130); var toRemoveSpeed = _dicByClientId.Where(a => a.Value.MinerActiveOn != DateTime.MinValue && a.Value.MinerActiveOn <= time).ToArray(); _speedDataRedis.DeleteByClientIdsAsync(toRemoveSpeed.Select(a => a.Key).ToArray()); // 删除一段时间没有活跃过的客户端 const int nDay = 7; DateTime netActiveOn = message.BornOn.AddSeconds(-30); time = message.BornOn.AddDays(-nDay); var toRemoveClient = _dicByObjectId.Where(a => a.Value.MinerActiveOn <= time && a.Value.NetActiveOn <= netActiveOn).ToArray(); if (toRemoveClient.Length > 0) { NTMinerConsole.UserOk($"{toRemoveClient.Length.ToString()} 台矿机因 {nDay.ToString()} 天没有活跃,删除对应记录"); foreach (var kv in toRemoveClient) { base.RemoveByObjectId(kv.Key); } } }, this.GetType()); // 收到Mq消息之前一定已经初始化完成,因为Mq消费者在ClientSetInitedEvent事件之后才会创建 VirtualRoot.BuildEventPath <SpeedDataMqMessage>("收到SpeedDataMq消息后更新ClientData内存", LogEnum.None, path: message => { if (message.AppId == ServerRoot.HostConfig.ThisServerAddress) { return; } if (message.ClientId == Guid.Empty) { return; } if (IsOldMqMessage(message.Timestamp)) { NTMinerConsole.UserOk(nameof(SpeedDataMqMessage) + ":" + MqKeyword.SafeIgnoreMessage); return; } speedDataRedis.GetByClientIdAsync(message.ClientId).ContinueWith(t => { ReportSpeed(t.Result.SpeedDto, message.MinerIp, isFromWsServerNode: true); }); }, this.GetType()); VirtualRoot.BuildEventPath <MinerClientWsOpenedMqMessage>("收到MinerClientWsOpenedMq消息后更新NetActiveOn和IsOnline", LogEnum.None, path: message => { if (IsOldMqMessage(message.Timestamp)) { NTMinerConsole.UserOk(nameof(MinerClientWsOpenedMqMessage) + ":" + MqKeyword.SafeIgnoreMessage); return; } if (_dicByClientId.TryGetValue(message.ClientId, out ClientData clientData)) { clientData.NetActiveOn = message.Timestamp; clientData.IsOnline = true; } }, this.GetType()); VirtualRoot.BuildEventPath <MinerClientWsClosedMqMessage>("收到MinerClientWsClosedMq消息后更新NetActiveOn和IsOnline", LogEnum.None, path: message => { if (IsOldMqMessage(message.Timestamp)) { NTMinerConsole.UserOk(nameof(MinerClientWsClosedMqMessage) + ":" + MqKeyword.SafeIgnoreMessage); return; } if (_dicByClientId.TryGetValue(message.ClientId, out ClientData clientData)) { clientData.NetActiveOn = message.Timestamp; clientData.IsOnline = false; } }, this.GetType()); VirtualRoot.BuildEventPath <MinerClientWsBreathedMqMessage>("收到MinerClientWsBreathedMq消息后更新NetActiveOn", LogEnum.None, path: message => { if (IsOldMqMessage(message.Timestamp)) { NTMinerConsole.UserOk(nameof(MinerClientWsBreathedMqMessage) + ":" + MqKeyword.SafeIgnoreMessage); return; } if (_dicByClientId.TryGetValue(message.ClientId, out ClientData clientData)) { clientData.NetActiveOn = message.Timestamp; clientData.IsOnline = true; } }, this.GetType()); VirtualRoot.BuildCmdPath <ChangeMinerSignMqMessage>(path: message => { if (_dicByObjectId.TryGetValue(message.Data.Id, out ClientData clientData)) { clientData.Update(message.Data, out bool isChanged); if (isChanged) { var minerData = MinerData.Create(clientData); _minerRedis.SetAsync(minerData).ContinueWith(t => { _mqSender.SendMinerSignChanged(minerData.Id); }); } } else { clientData = ClientData.Create(MinerData.Create(message.Data)); Add(clientData); } clientData.NetActiveOn = DateTime.Now; clientData.IsOnline = true; clientData.IsOuterUserEnabled = true; }, this.GetType(), LogEnum.None); VirtualRoot.BuildCmdPath <QueryClientsForWsMqMessage>(path: message => { QueryClientsResponse response = AppRoot.QueryClientsForWs(message.Query); _mqSender.SendResponseClientsForWs(message.AppId, message.LoginName, message.SessionId, response); }, this.GetType(), LogEnum.None); }
public ClientDataSet( IMinerDataRedis minerRedis, IClientActiveOnRedis clientActiveOnRedis, ISpeedDataRedis speedDataRedis, IMinerClientMqSender mqSender) : base(isPull: false, getDatas: callback => { var getMinersTask = minerRedis.GetAllAsync(); var getClientActiveOnsTask = clientActiveOnRedis.GetAllAsync(); var getSpeedsTask = speedDataRedis.GetAllAsync(); Task.WhenAll(getMinersTask, getClientActiveOnsTask, getSpeedsTask).ContinueWith(t => { NTMinerConsole.UserInfo($"从redis加载了 {getMinersTask.Result.Count} 条MinerData,和 {getSpeedsTask.Result.Count} 条SpeedData"); Dictionary <Guid, SpeedData> speedDataDic = getSpeedsTask.Result; Dictionary <string, DateTime> clientActiveOnDic = getClientActiveOnsTask.Result; List <ClientData> clientDatas = new List <ClientData>(); DateTime speedOn = DateTime.Now.AddMinutes(-3); foreach (var minerData in getMinersTask.Result) { var clientData = ClientData.Create(minerData); if (clientActiveOnDic.TryGetValue(minerData.Id, out DateTime activeOn)) { clientData.MinerActiveOn = activeOn; } clientDatas.Add(clientData); if (speedDataDic.TryGetValue(minerData.ClientId, out SpeedData speedData) && speedData.SpeedOn > speedOn) { clientData.Update(speedData, out bool _); } } callback?.Invoke(clientDatas); }); }) { _minerRedis = minerRedis; _clientActiveOnRedis = clientActiveOnRedis; _speedDataRedis = speedDataRedis; _mqSender = mqSender; VirtualRoot.BuildEventPath <Per100MinuteEvent>("周期将矿机的MinerActiveOn或NetActiveOn时间戳持久到redis", LogEnum.DevConsole, message => { var minerCients = _dicByObjectId.Values.ToArray(); DateTime time = message.BornOn.AddSeconds(-message.Seconds); int count = 0; foreach (var minerClient in minerCients) { // 如果活跃则更新到redis,否则就不更新了 DateTime activeOn = minerClient.GetActiveOn(); if (activeOn > time) { clientActiveOnRedis.SetAsync(minerClient.Id, activeOn); count++; } } NTMinerConsole.DevWarn($"{count.ToString()} 条活跃矿机的时间戳被持久化"); }, this.GetType()); // 上面的持久化时间戳到redis的目的主要是为了下面那个周期找出不活跃的矿机记录删除掉的逻辑能够在重启WebApiServer服务进程后不中断 VirtualRoot.BuildEventPath <Per2MinuteEvent>("周期找出用不活跃的矿机记录删除掉", LogEnum.DevConsole, message => { var clientDatas = _dicByObjectId.Values.ToArray(); Dictionary <string, List <ClientData> > dicByMACAddress = new Dictionary <string, List <ClientData> >(); DateTime minerClientExpireTime = message.BornOn.AddDays(-7); // 因为SpeedData尺寸较大,时效性较短,可以比CientData更早删除 DateTime minerSpeedExpireTime = message.BornOn.AddMinutes(-3); int count = 0; foreach (var clientData in clientDatas) { DateTime activeOn = clientData.GetActiveOn(); // 如果7天都没有活跃了 if (activeOn <= minerClientExpireTime) { RemoveByObjectId(clientData.Id); count++; } else if (activeOn <= minerSpeedExpireTime) { _speedDataRedis.DeleteByClientIdAsync(clientData.ClientId); } else if (!string.IsNullOrEmpty(clientData.MACAddress)) { if (!dicByMACAddress.TryGetValue(clientData.MACAddress, out List <ClientData> list)) { list = new List <ClientData>(); dicByMACAddress.Add(clientData.MACAddress, list); } list.Add(clientData); } } if (count > 0) { NTMinerConsole.DevWarn($"{count.ToString()} 条不活跃的矿机记录被删除"); } List <string> toRemoveIds = new List <string>(); foreach (var kv in dicByMACAddress) { if (kv.Value.Count > 1) { toRemoveIds.AddRange(kv.Value.Select(a => a.Id)); } } if (toRemoveIds.Count > 0) { count = 0; foreach (var id in toRemoveIds) { RemoveByObjectId(id); count++; } NTMinerConsole.DevWarn($"{count.ToString()} 条MAC地址重复的矿机记录被删除"); } NTMinerConsole.DevDebug($"QueryClients平均耗时 {AverageQueryClientsMilliseconds.ToString()} 毫秒"); }, this.GetType()); // 收到Mq消息之前一定已经初始化完成,因为Mq消费者在ClientSetInitedEvent事件之后才会创建 VirtualRoot.BuildEventPath <SpeedDatasMqEvent>("收到SpeedDatasMq消息后更新ClientData内存", LogEnum.None, path: message => { if (message.AppId == ServerRoot.HostConfig.ThisServerAddress) { return; } if (message.ClientIdIps == null || message.ClientIdIps.Length == 0) { return; } if (IsOldMqMessage(message.Timestamp)) { NTMinerConsole.UserOk(nameof(SpeedDatasMqEvent) + ":" + MqKeyword.SafeIgnoreMessage); return; } speedDataRedis.GetByClientIdsAsync(message.ClientIdIps.Select(a => a.ClientId).ToArray()).ContinueWith(t => { if (t.Result != null && t.Result.Length != 0) { foreach (var item in t.Result) { string minerIp = string.Empty; var clientIdIp = message.ClientIdIps.FirstOrDefault(a => a.ClientId == item.ClientId); if (clientIdIp != null) { minerIp = clientIdIp.MinerIp; } ReportSpeed(item.SpeedDto, minerIp, isFromWsServerNode: true); } } }); }, this.GetType()); VirtualRoot.BuildEventPath <MinerClientWsClosedMqEvent>("收到MinerClientWsClosedMq消息后更新NetActiveOn和IsOnline", LogEnum.None, path: message => { if (IsOldMqMessage(message.Timestamp)) { NTMinerConsole.UserOk(nameof(MinerClientWsClosedMqEvent) + ":" + MqKeyword.SafeIgnoreMessage); return; } if (_dicByClientId.TryGetValue(message.ClientId, out ClientData clientData)) { clientData.NetActiveOn = message.Timestamp; clientData.IsOnline = false; } }, this.GetType()); VirtualRoot.BuildEventPath <MinerClientsWsBreathedMqEvent>("收到MinerClientsWsBreathedMq消息后更新NetActiveOn", LogEnum.None, path: message => { if (IsOldMqMessage(message.Timestamp)) { NTMinerConsole.UserOk(nameof(MinerClientsWsBreathedMqEvent) + ":" + MqKeyword.SafeIgnoreMessage); return; } if (message.ClientIds != null && message.ClientIds.Length != 0) { foreach (var clientId in message.ClientIds) { if (_dicByClientId.TryGetValue(clientId, out ClientData clientData)) { clientData.NetActiveOn = message.Timestamp; clientData.IsOnline = true; } } } }, this.GetType()); VirtualRoot.BuildEventPath <MinerSignSetedMqEvent>("更新内存中的MinerData的MinerSign部分", LogEnum.None, path: message => { if (_dicByObjectId.TryGetValue(message.Data.Id, out ClientData clientData)) { clientData.Update(message.Data); } else { clientData = ClientData.Create(message.Data); Add(clientData); } clientData.NetActiveOn = DateTime.Now; clientData.IsOnline = true; clientData.IsOuterUserEnabled = true; }, this.GetType()); VirtualRoot.BuildCmdPath <QueryClientsForWsMqCommand>(path: message => { QueryClientsResponse response = AppRoot.QueryClientsForWs(message.Query); _mqSender.SendResponseClientsForWs(message.AppId, message.LoginName, message.SessionId, message.MqMessageId, response); }, this.GetType(), LogEnum.None); }
public ClientDataSet(IMinerRedis minerRedis, ISpeedDataRedis speedDataRedis, IMinerClientMqSender mqSender) : base(isPull: false, getDatas: callback => { var getMinersTask = minerRedis.GetAllAsync(); var getSpeedsTask = speedDataRedis.GetAllAsync(); Task.WhenAll(getMinersTask, getSpeedsTask).ContinueWith(t => { NTMinerConsole.UserInfo($"从redis加载了 {getMinersTask.Result.Count} 条MinerData,和 {getSpeedsTask.Result.Count} 条SpeedData"); var speedDatas = getSpeedsTask.Result; List <ClientData> clientDatas = new List <ClientData>(); DateTime speedOn = DateTime.Now.AddMinutes(-3); foreach (var minerData in getMinersTask.Result) { var clientData = ClientData.Create(minerData); // 该属性没有持久化而只在内存中,启动时将该属性值视为当前日期的前一天的零时加上CreatedOn的时间,别处有个周期清理7天不活跃矿机的任务 clientData.MinerActiveOn = DateTime.Today.AddDays(-1) + minerData.CreatedOn.TimeOfDay; clientDatas.Add(clientData); var speedData = speedDatas.FirstOrDefault(a => a.ClientId == minerData.ClientId); if (speedData != null && speedData.SpeedOn > speedOn) { clientData.Update(speedData, out bool _); } } callback?.Invoke(clientDatas); }); }) { _minerRedis = minerRedis; _speedDataRedis = speedDataRedis; _mqSender = mqSender; VirtualRoot.BuildEventPath <Per1MinuteEvent>("周期清理Redis中不活跃的来自挖矿端上报的算力记录", LogEnum.DevConsole, path: message => { DateTime time = message.BornOn.AddSeconds(-130); var toRemoveSpeed = _dicByClientId.Where(a => a.Value.MinerActiveOn != DateTime.MinValue && a.Value.MinerActiveOn <= time).ToArray(); _speedDataRedis.DeleteByClientIdsAsync(toRemoveSpeed.Select(a => a.Key).ToArray()); // 删除一周没有活跃过的客户端 time = message.BornOn.AddDays(-7); var toRemoveClient = _dicByObjectId.Where(a => a.Value.MinerActiveOn <= time).ToArray(); foreach (var kv in toRemoveClient) { base.RemoveByObjectId(kv.Key); } }, this.GetType()); // 收到Mq消息之前一定已经初始化完成,因为Mq消费者在ClientSetInitedEvent事件之后才会创建 VirtualRoot.BuildEventPath <SpeedDataMqMessage>("收到SpeedDataMq消息后更新ClientData内存", LogEnum.None, path: message => { if (message.AppId == ServerRoot.HostConfig.ThisServerAddress) { return; } if (message.ClientId == Guid.Empty) { return; } if (IsOldMqMessage(message.Timestamp)) { NTMinerConsole.UserOk(_safeIgnoreMessage); return; } speedDataRedis.GetByClientIdAsync(message.ClientId).ContinueWith(t => { ReportSpeed(t.Result.SpeedDto, message.MinerIp, isFromWsServerNode: true); }); }, this.GetType()); VirtualRoot.BuildEventPath <MinerClientWsOpenedMqMessage>("收到MinerClientWsOpenedMq消息后更新NetActiveOn和IsOnline", LogEnum.None, path: message => { if (IsOldMqMessage(message.Timestamp)) { NTMinerConsole.UserOk(_safeIgnoreMessage); return; } if (_dicByClientId.TryGetValue(message.ClientId, out ClientData clientData)) { clientData.NetActiveOn = message.Timestamp; clientData.IsOnline = true; } }, this.GetType()); VirtualRoot.BuildEventPath <MinerClientWsClosedMqMessage>("收到MinerClientWsClosedMq消息后更新NetActiveOn和IsOnline", LogEnum.None, path: message => { if (IsOldMqMessage(message.Timestamp)) { NTMinerConsole.UserOk(_safeIgnoreMessage); return; } if (_dicByClientId.TryGetValue(message.ClientId, out ClientData clientData)) { clientData.NetActiveOn = message.Timestamp; clientData.IsOnline = false; } }, this.GetType()); VirtualRoot.BuildEventPath <MinerClientWsBreathedMqMessage>("收到MinerClientWsBreathedMq消息后更新NetActiveOn", LogEnum.None, path: message => { if (IsOldMqMessage(message.Timestamp)) { NTMinerConsole.UserOk(_safeIgnoreMessage); return; } if (_dicByClientId.TryGetValue(message.ClientId, out ClientData clientData)) { clientData.NetActiveOn = message.Timestamp; clientData.IsOnline = true; } }, this.GetType()); VirtualRoot.BuildCmdPath <ChangeMinerSignMqMessage>(path: message => { if (_dicByObjectId.TryGetValue(message.Data.Id, out ClientData clientData)) { clientData.Update(message.Data, out bool isChanged); if (isChanged) { var minerData = MinerData.Create(clientData); _minerRedis.SetAsync(minerData).ContinueWith(t => { _mqSender.SendMinerSignChanged(minerData.Id); }); } } else { // 此时该矿机是第一次在服务端出现 NTMinerConsole.UserWarn("该矿机首次出现于WsServer:" + VirtualRoot.JsonSerializer.Serialize(message.Data)); clientData = ClientData.Create(MinerData.Create(message.Data)); clientData.NetActiveOn = DateTime.Now; clientData.IsOnline = true; clientData.IsOuterUserEnabled = true; Add(clientData); } }, this.GetType(), LogEnum.None); }
public MinerSignSet(IMinerDataRedis redis) { _redis = redis; Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); redis.GetAllAsync().ContinueWith(t => { _initedOn = DateTime.Now; foreach (var item in t.Result) { _dicByClientId[item.ClientId] = MinerSign.Create(item); } IsReadied = true; stopwatch.Stop(); NTMinerConsole.UserOk($"矿机签名集就绪,耗时 {stopwatch.GetElapsedSeconds().ToString("f2")} 秒"); VirtualRoot.RaiseEvent(new MinerSignSetInitedEvent()); }); // 收到Mq消息之前一定已经初始化完成,因为Mq消费者在MinerSignSetInitedEvent事件之后才会创建 VirtualRoot.BuildEventPath <MinerDataRemovedMqEvent>("收到MinerClientRemovedMq消息后移除内存中对应的记录", LogEnum.None, this.GetType(), PathPriority.Normal, path: message => { #region if (message.AppId == ServerRoot.HostConfig.ThisServerAddress) { return; } if (IsOldMqMessage(message.Timestamp)) { NTMinerConsole.UserOk(nameof(MinerDataRemovedMqEvent) + ":" + MqKeyword.SafeIgnoreMessage); return; } if (_dicByClientId.TryRemove(message.ClientId, out MinerSign minerSign)) { if (AppRoot.MinerClientSessionSet.TryGetByClientId(minerSign.ClientId, out IMinerClientSession ntminerSession)) { ntminerSession.CloseAsync(WsCloseCode.Normal, "服务端移除了该矿机"); } } #endregion }); VirtualRoot.BuildEventPath <MinerDatasRemovedMqEvent>("收到MinerClientsRemovedMq消息后移除内存中对应的记录", LogEnum.None, this.GetType(), PathPriority.Normal, path: message => { #region if (message.AppId == ServerRoot.HostConfig.ThisServerAddress) { return; } if (IsOldMqMessage(message.Timestamp)) { NTMinerConsole.UserOk(nameof(MinerDataRemovedMqEvent) + ":" + MqKeyword.SafeIgnoreMessage); return; } foreach (var clientId in message.ClientIds) { if (_dicByClientId.TryRemove(clientId, out MinerSign minerSign)) { if (AppRoot.MinerClientSessionSet.TryGetByClientId(clientId, out IMinerClientSession ntminerSession)) { ntminerSession.CloseAsync(WsCloseCode.Normal, "服务端移除了该矿机"); } } } #endregion }); VirtualRoot.BuildEventPath <Per1SecondEvent>("每秒钟将暂存的新设置的MinerSign发送到Mq", LogEnum.None, this.GetType(), PathPriority.Normal, message => { Task.Factory.StartNew(() => { MinerSign[] minerSignsSeted; lock (_lockForMinerSignsSeted) { minerSignsSeted = _minerSignsSeted.ToArray(); _minerSignsSeted.Clear(); } AppRoot.MinerClientMqSender.SendMinerSignsSeted(minerSignsSeted); }); }); }
public ReadOnlyUserSet(IReadOnlyUserRedis userRedis) { userRedis.GetAllAsync().ContinueWith(t => { _initedOn = DateTime.Now; foreach (var item in t.Result) { _dicByLoginName.Add(item.LoginName, item); } IsReadied = true; NTMinerConsole.UserOk("用户集就绪"); VirtualRoot.RaiseEvent(new UserSetInitedEvent()); }); // 收到Mq消息之前一定已经初始化完成,因为Mq消费者在UserSetInitedEvent事件之后才会创建 VirtualRoot.AddEventPath <UserAddedMqMessage>("收到UserAddedMq消息后从Redis加载新用户到内存", LogEnum.None, action: message => { if (message.AppId == ServerRoot.HostConfig.ThisServerAddress) { return; } if (string.IsNullOrEmpty(message.LoginName)) { return; } if (IsOldMqMessage(message.Timestamp)) { NTMinerConsole.UserOk(_safeIgnoreMessage); return; } userRedis.GetByLoginNameAsync(message.LoginName).ContinueWith(t => { if (t.Result != null) { _dicByLoginName[message.LoginName] = t.Result; } }); }, this.GetType()); VirtualRoot.AddEventPath <UserUpdatedMqMessage>("收到UserUpdatedMq消息后从Redis加载用户到内存", LogEnum.None, action: message => { if (message.AppId == ServerRoot.HostConfig.ThisServerAddress) { return; } if (string.IsNullOrEmpty(message.LoginName)) { return; } if (IsOldMqMessage(message.Timestamp)) { NTMinerConsole.UserOk(_safeIgnoreMessage); return; } userRedis.GetByLoginNameAsync(message.LoginName).ContinueWith(t => { if (t.Result != null) { _dicByLoginName[message.LoginName] = t.Result; } }); }, this.GetType()); VirtualRoot.AddEventPath <UserRemovedMqMessage>("收到UserRemovedMq消息后移除内存中对应的记录", LogEnum.None, action: message => { if (message.AppId == ServerRoot.HostConfig.ThisServerAddress) { return; } if (string.IsNullOrEmpty(message.LoginName)) { return; } if (IsOldMqMessage(message.Timestamp)) { NTMinerConsole.UserOk(_safeIgnoreMessage); return; } _dicByLoginName.Remove(message.LoginName); }, this.GetType()); VirtualRoot.AddEventPath <UserEnabledMqMessage>("收到UserEnabledMq消息后启用内存中对应记录的状态", LogEnum.None, action: message => { if (message.AppId == ServerRoot.HostConfig.ThisServerAddress) { return; } if (string.IsNullOrEmpty(message.LoginName)) { return; } if (IsOldMqMessage(message.Timestamp)) { NTMinerConsole.UserOk(_safeIgnoreMessage); return; } if (_dicByLoginName.TryGetValue(message.LoginName, out UserData userData)) { userData.IsEnabled = true; } }, this.GetType()); VirtualRoot.AddEventPath <UserDisabledMqMessage>("收到UserDisabledMq消息后禁用内存中对应记录的状态", LogEnum.None, action: message => { if (message.AppId == ServerRoot.HostConfig.ThisServerAddress) { return; } if (string.IsNullOrEmpty(message.LoginName)) { return; } if (IsOldMqMessage(message.Timestamp)) { NTMinerConsole.UserOk(_safeIgnoreMessage); return; } if (_dicByLoginName.TryGetValue(message.LoginName, out UserData userData)) { userData.IsEnabled = false; } }, this.GetType()); VirtualRoot.AddEventPath <UserPasswordChangedMqMessage>("收到UserPasswordChangedMq消息后从Redis刷新内存中对应的记录", LogEnum.None, action: message => { if (message.AppId == ServerRoot.HostConfig.ThisServerAddress) { return; } if (string.IsNullOrEmpty(message.LoginName)) { return; } if (IsOldMqMessage(message.Timestamp)) { NTMinerConsole.UserOk(_safeIgnoreMessage); return; } userRedis.GetByLoginNameAsync(message.LoginName).ContinueWith(t => { if (t.Result != null) { _dicByLoginName[message.LoginName] = t.Result; } }); }, this.GetType()); VirtualRoot.AddEventPath <UserRSAKeyUpdatedMqMessage>("收到了UserRSAKeyUpdated Mq消息后更新内存中对应的记录", LogEnum.None, action: message => { if (message.AppId == ServerRoot.HostConfig.ThisServerAddress) { return; } if (string.IsNullOrEmpty(message.LoginName)) { return; } if (IsOldMqMessage(message.Timestamp)) { NTMinerConsole.UserOk(_safeIgnoreMessage); return; } if (_dicByLoginName.TryGetValue(message.LoginName, out UserData userData)) { userRedis.GetByLoginNameAsync(message.LoginName).ContinueWith(t => { if (t.Result != null) { _dicByLoginName[message.LoginName] = t.Result; } }); } }, this.GetType()); }
public ReadOnlyUserSet(IReadOnlyUserDataRedis userRedis) { Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); userRedis.GetAllAsync().ContinueWith(t => { _initedOn = DateTime.Now; foreach (var item in t.Result) { _dicByLoginName.Add(item.LoginName, item); } IsReadied = true; stopwatch.Stop(); NTMinerConsole.UserOk($"用户集就绪,耗时 {stopwatch.GetElapsedSeconds().ToString("f2")} 秒"); VirtualRoot.RaiseEvent(new UserSetInitedEvent()); }); // 收到Mq消息之前一定已经初始化完成,因为Mq消费者在UserSetInitedEvent事件之后才会创建 VirtualRoot.BuildEventPath <UserAddedMqEvent>("收到UserAddedMq消息后从Redis加载新用户到内存", LogEnum.None, this.GetType(), PathPriority.Normal, path: message => { if (message.AppId == ServerRoot.HostConfig.ThisServerAddress) { return; } if (string.IsNullOrEmpty(message.LoginName)) { return; } if (IsOldMqMessage(message.Timestamp)) { NTMinerConsole.UserOk(nameof(UserAddedMqEvent) + ":" + MqKeyword.SafeIgnoreMessage); return; } userRedis.GetByLoginNameAsync(message.LoginName).ContinueWith(t => { if (t.Result != null) { _dicByLoginName[message.LoginName] = t.Result; } }); }); VirtualRoot.BuildEventPath <UserUpdatedMqEvent>("收到UserUpdatedMq消息后从Redis加载用户到内存", LogEnum.None, this.GetType(), PathPriority.Normal, path: message => { if (message.AppId == ServerRoot.HostConfig.ThisServerAddress) { return; } if (string.IsNullOrEmpty(message.LoginName)) { return; } if (IsOldMqMessage(message.Timestamp)) { NTMinerConsole.UserOk(nameof(UserUpdatedMqEvent) + ":" + MqKeyword.SafeIgnoreMessage); return; } userRedis.GetByLoginNameAsync(message.LoginName).ContinueWith(t => { if (t.Result != null) { _dicByLoginName[message.LoginName] = t.Result; } }); }); VirtualRoot.BuildEventPath <UserRemovedMqEvent>("收到UserRemovedMq消息后移除内存中对应的记录", LogEnum.None, this.GetType(), PathPriority.Normal, path: message => { if (message.AppId == ServerRoot.HostConfig.ThisServerAddress) { return; } if (string.IsNullOrEmpty(message.LoginName)) { return; } if (IsOldMqMessage(message.Timestamp)) { NTMinerConsole.UserOk(nameof(UserRemovedMqEvent) + ":" + MqKeyword.SafeIgnoreMessage); return; } _dicByLoginName.Remove(message.LoginName); }); VirtualRoot.BuildEventPath <UserEnabledMqEvent>("收到UserEnabledMq消息后启用内存中对应记录的状态", LogEnum.None, this.GetType(), PathPriority.Normal, path: message => { if (message.AppId == ServerRoot.HostConfig.ThisServerAddress) { return; } if (string.IsNullOrEmpty(message.LoginName)) { return; } if (IsOldMqMessage(message.Timestamp)) { NTMinerConsole.UserOk(nameof(UserEnabledMqEvent) + ":" + MqKeyword.SafeIgnoreMessage); return; } if (_dicByLoginName.TryGetValue(message.LoginName, out UserData userData)) { userData.IsEnabled = true; } }); VirtualRoot.BuildEventPath <UserDisabledMqEvent>("收到UserDisabledMq消息后禁用内存中对应记录的状态", LogEnum.None, this.GetType(), PathPriority.Normal, path: message => { if (message.AppId == ServerRoot.HostConfig.ThisServerAddress) { return; } if (string.IsNullOrEmpty(message.LoginName)) { return; } if (IsOldMqMessage(message.Timestamp)) { NTMinerConsole.UserOk(nameof(UserDisabledMqEvent) + ":" + MqKeyword.SafeIgnoreMessage); return; } if (_dicByLoginName.TryGetValue(message.LoginName, out UserData userData)) { userData.IsEnabled = false; } }); VirtualRoot.BuildEventPath <UserPasswordChangedMqEvent>("收到UserPasswordChangedMq消息后从Redis刷新内存中对应的记录", LogEnum.None, this.GetType(), PathPriority.Normal, path: message => { if (message.AppId == ServerRoot.HostConfig.ThisServerAddress) { return; } if (string.IsNullOrEmpty(message.LoginName)) { return; } if (IsOldMqMessage(message.Timestamp)) { NTMinerConsole.UserOk(nameof(UserPasswordChangedMqEvent) + ":" + MqKeyword.SafeIgnoreMessage); return; } userRedis.GetByLoginNameAsync(message.LoginName).ContinueWith(t => { if (t.Result != null) { _dicByLoginName[message.LoginName] = t.Result; } }); }); VirtualRoot.BuildEventPath <UserRSAKeyUpdatedMqEvent>("收到了UserRSAKeyUpdated Mq消息后更新内存中对应的记录", LogEnum.None, this.GetType(), PathPriority.Normal, path: message => { if (message.AppId == ServerRoot.HostConfig.ThisServerAddress) { return; } if (string.IsNullOrEmpty(message.LoginName)) { return; } if (IsOldMqMessage(message.Timestamp)) { NTMinerConsole.UserOk(nameof(UserRSAKeyUpdatedMqEvent) + ":" + MqKeyword.SafeIgnoreMessage); return; } if (_dicByLoginName.TryGetValue(message.LoginName, out UserData userData)) { userRedis.GetByLoginNameAsync(message.LoginName).ContinueWith(t => { if (t.Result != null) { _dicByLoginName[message.LoginName] = t.Result; } }); } }); }
public MinerSignSet(IReadOnlyMinerRedis redis) { redis.GetAllAsync().ContinueWith(t => { _initedOn = DateTime.Now; foreach (var item in t.Result) { Add(MinerSign.Create(item)); } IsReadied = true; NTMinerConsole.UserOk("矿机签名集就绪"); VirtualRoot.RaiseEvent(new MinerSignSetInitedEvent()); }); // 收到Mq消息之前一定已经初始化完成,因为Mq消费者在MinerSignSetInitedEvent事件之后才会创建 VirtualRoot.BuildEventPath <MinerDataRemovedMqMessage>("收到MinerClientRemovedMq消息后移除内存中对应的记录", LogEnum.None, path: message => { #region if (message.AppId == ServerRoot.HostConfig.ThisServerAddress) { return; } if (string.IsNullOrEmpty(message.MinerId)) { return; } if (IsOldMqMessage(message.Timestamp)) { NTMinerConsole.UserOk(nameof(MinerDataRemovedMqMessage) + ":" + MqKeyword.SafeIgnoreMessage); return; } if (_dicByMinerId.TryGetValue(message.MinerId, out MinerSign minerSign)) { if (AppRoot.MinerClientSessionSet.TryGetByClientId(minerSign.ClientId, out IMinerClientSession ntminerSession)) { ntminerSession.CloseAsync(WsCloseCode.Normal, "服务端移除了该矿机"); } _dicByMinerId.Remove(message.MinerId); _dicByClientId.Remove(minerSign.ClientId); } #endregion }, this.GetType()); VirtualRoot.BuildEventPath <MinerDataAddedMqMessage>("收到MinerDataAddedMq消息后更新内存中对应的记录", LogEnum.None, path: message => { #region if (message.AppId == ServerRoot.HostConfig.ThisServerAddress) { return; } if (string.IsNullOrEmpty(message.MinerId)) { return; } if (IsOldMqMessage(message.Timestamp)) { NTMinerConsole.UserOk(nameof(MinerDataAddedMqMessage) + ":" + MqKeyword.SafeIgnoreMessage); return; } redis.GetByIdAsync(message.MinerId).ContinueWith(t => { if (t.Result != null) { if (_dicByMinerId.TryGetValue(message.MinerId, out MinerSign minerSign)) { minerSign.Update(t.Result); } else { Add(MinerSign.Create(t.Result)); } } }); #endregion }, this.GetType()); VirtualRoot.BuildEventPath <MinerSignChangedMqMessage>("收到MinerSignChangedMq消息后更新内存中对应的记录", LogEnum.None, path: message => { #region if (message.AppId == ServerRoot.HostConfig.ThisServerAddress) { return; } if (string.IsNullOrEmpty(message.MinerId)) { return; } if (IsOldMqMessage(message.Timestamp)) { NTMinerConsole.UserOk(nameof(MinerSignChangedMqMessage) + ":" + MqKeyword.SafeIgnoreMessage); return; } redis.GetByIdAsync(message.MinerId).ContinueWith(t => { if (t.Result != null) { if (_dicByMinerId.TryGetValue(message.MinerId, out MinerSign minerSign)) { minerSign.Update(t.Result); } else { Add(MinerSign.Create(t.Result)); } } }); #endregion }, this.GetType()); }
public void OkWriteLine(object message) { NTMinerConsole.UserOk(message?.ToString()); _log.Info(message); }
public MinerSignSet(IMinerDataRedis redis) { _redis = redis; Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); redis.GetAllAsync().ContinueWith(t => { _initedOn = DateTime.Now; foreach (var item in t.Result) { _dicByClientId[item.ClientId] = MinerSign.Create(item); } IsReadied = true; stopwatch.Stop(); NTMinerConsole.UserOk($"矿机签名集就绪,耗时 {stopwatch.GetElapsedSeconds().ToString("f2")} 秒"); VirtualRoot.RaiseEvent(new MinerSignSetInitedEvent()); }); // 收到Mq消息之前一定已经初始化完成,因为Mq消费者在MinerSignSetInitedEvent事件之后才会创建 VirtualRoot.BuildEventPath <MinerDataRemovedMqEvent>("收到MinerClientRemovedMq消息后移除内存中对应的记录", LogEnum.None, path: message => { #region if (message.AppId == ServerRoot.HostConfig.ThisServerAddress) { return; } if (string.IsNullOrEmpty(message.MinerId)) { return; } if (IsOldMqMessage(message.Timestamp)) { NTMinerConsole.UserOk(nameof(MinerDataRemovedMqEvent) + ":" + MqKeyword.SafeIgnoreMessage); return; } if (_dicByClientId.TryRemove(message.ClientId, out MinerSign minerSign)) { if (AppRoot.MinerClientSessionSet.TryGetByClientId(minerSign.ClientId, out IMinerClientSession ntminerSession)) { ntminerSession.CloseAsync(WsCloseCode.Normal, "服务端移除了该矿机"); } } #endregion }, this.GetType()); VirtualRoot.BuildEventPath <MinerSignSetedMqEvent>("收到MinerSignSetedMq消息后更新内存中对应的记录", LogEnum.None, path: message => { #region if (message.AppId == ServerRoot.HostConfig.ThisServerAddress) { return; } if (message.Data == null) { return; } if (IsOldMqMessage(message.Timestamp)) { NTMinerConsole.UserOk(nameof(MinerSignSetedMqEvent) + ":" + MqKeyword.SafeIgnoreMessage); return; } _dicByClientId[message.Data.ClientId] = message.Data; #endregion }, this.GetType()); }