/// <summary> /// 启动,软停止和硬停止都可用 /// </summary> public void Start() { if (!isRunning) { isRunning = true; tcpServer.Start(); //每两秒扫描一次命令缓冲区 ScanActionTimer = YUtil.SetInterval(2000, () => { using (ActionLock.Lock()) { //自动执行任务 var canClear = true; foreach (var pair in ActionCache) { if (pair.Value != SmAction.NoAction && ActionClientDict.ContainsKey(pair.Key)) { try { var state = ActionClientDict[pair.Key]; tcpServer.Send(state, SmParamApi.BuildAlarmPackage(state.ModuleAddr, pair.Value)); Logger.Debug($"发送命令 {Enum.GetName(typeof(SmAction), pair.Value)} 成功 {pair.Key}"); ActionCache[pair.Key] = SmAction.NoAction; } catch { canClear = false; Logger.Error($"发送命令 {Enum.GetName(typeof(SmAction), pair.Value)} 异常 {pair.Key}", 24 * 3600); } } } if (canClear) { YUtil.ClearTimeout(ScanActionTimer); } } }); } }
/// <summary> /// 接受到数据并处理 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void onDataReceived(object sender, YTcpSrvEventArgs e) { if (!isRunning) { return; } var ip = e.State.TcpClientIP; //一分钟输出一次,某个ip正在活动 Logger.Debug($"{ip} 正在活动", ConsoleColor.DarkGreen, 60000); if (e.State.BufferCount >= e.State.Buffer.Length) { e.State.BufferCount = 0; } var reBuffer = e.State.Buffer; var reCount = e.State.BufferCount; //取得ip对应的缓存区 if (!SmClientManager.IPSessionBuffer.ContainsKey(ip)) { SmClientManager.IPSessionBuffer[ip] = SmClientManager.DefaultBuffer(); } List <SmModel> smModels; //解析套接字数据 using (var analysis = new SmAnalysis(SmClientManager.IPSessionBuffer[ip], Logger)) { smModels = analysis.ThroughAnalysisStack(reBuffer, 0, reCount); if (smModels?.Count == 0) { Logger.Debug($"{ip} 包解析失败", ConsoleColor.Red); return; } smModels?.ForEach(sm => { //按协议应给客户端回复 if (sm.PackageType == SmPackageType.ParamPackage || sm.PackageType == SmPackageType.HeartbeatPackage) { var replayPkg = SmParamApi.BuildParamPackage((byte)(sm.Cmd + 0x80), null, 2, sm.ModuleAddr); try { tcpServer.Send(e.State.TcpClient, replayPkg); } catch { Logger.Error($"回复客户端:{ip} 异常"); } } }); //设置模块地址 if (smModels?.Count > 0 && e.State.ModuleAddr == null) { e.State.ModuleAddr = smModels[0].ModuleAddr; } } if (smModels?.Count > 0) { OnDataReceivedAction?.Invoke(ip, smModels); } }
/// <summary> /// 向某个ip发送命令,这里的ip必须是底层可以执行动作的ip /// </summary> /// <param name="ip"></param> /// <param name="action"></param> public void SendAction(string ip, SmAction action) { using (ActionLock.Lock()) { if (ActionClientDict.TryGetValue(ip, out var state)) { try { tcpServer.Send(state, SmParamApi.BuildAlarmPackage(state.ModuleAddr, action)); Logger.Debug($"发送命令 {Enum.GetName(typeof(SmAction), action)} 成功 {ip}"); ActionCache[ip] = SmAction.NoAction; } catch { ActionCache[ip] = action; YUtil.RecoveryTimeout(ScanActionTimer); } } } }