using SuperSocket.SocketBase; using SuperSocket.SocketBase.Protocol; using System.Collections.Generic; using System; using Quartz; using Quartz.Impl; using SensorHub.Utility; using System.Timers; using Newtonsoft.Json.Linq; using Newtonsoft.Json; using SensorHub.Servers.JsonFormat; using SensorHub.Servers.Commands.CASICCommands; using StackExchange.Redis; using System.Threading; using System.Diagnostics; using SensorHub.Config; namespace SensorHub.Servers { public class CasicServer433 : AppServer<CasicSession>, IDespatchServer { RedisHelper redis = new RedisHelper(0);//依赖Redis的可靠性,如果Redis服务停止,需要重启本程序,希望以后可以改善 private List<String> concentratorThreadList = new List<String>(); //public static Dictionary<String, String> concentratorWithSessionIdMap = new Dictionary<String, String>(); public CasicServer433() : base(new DefaultReceiveFilterFactory<CasicReceiveFilter433, StringRequestInfo>()) { } protected override void OnStarted() { redis.Subscribe("Config", (channel, message) => { //输出收到的订阅消息 Logger.Info("收到订阅的Config消息:" + message); String[] concentratorCodes = message.ToString().Split(','); foreach (var concentratorCode in concentratorCodes) { if (!Common.concentratorWithSessionIdMap.ContainsKey(concentratorCode)) { return; } if (!concentratorThreadList.Contains(concentratorCode)) { Thread t = new Thread(doSendConfig); t.Start(concentratorCode); concentratorThreadList.Add(concentratorCode); } } }); } private void doSendConfig(object msg) //下发配置线程 { String code = msg as String; Dictionary<String, int> devWithMaxSendNumbers = new Dictionary<String, int>(); try { while (true) { String devcodes = redis.ListRightPop<String>(code); if (string.IsNullOrEmpty(devcodes)) { break; } if (!devcodes.Contains(":")) { devcodes += ":1"; } String[] devcode = devcodes.Split(':');//设备编号:尝试次数 Logger.Info("设备[" + devcode[0] + "]剩余主动下发配置尝试次数:" + devcode[1]); String devCode = devcode[0].Replace("$", "").Substring(0,12); String devType = devCode.Substring(0, 2); int interval = 0;//下发时间间隔 byte routeflag = 0x01;//通信方式,路灯为05 if (devType == "72" || devType == "73" || devType == "74")//路灯时间长 { interval = int.Parse(System.Configuration.ConfigurationManager.AppSettings["Lamp_Interval"]); routeflag = 0x05; } else { interval = int.Parse(System.Configuration.ConfigurationManager.AppSettings["Concentrator_Interval"]); //interval = 10000; } String configItem = redis.StringGet(devcode[0]); if (string.IsNullOrEmpty(configItem)) { redis.ListRemove<String>(code, devcode[0]); Logger.Info("设备[" + devcode[0] + "]已下发成功,下发配置项为空"); continue; } byte[] config = null; if (configItem.Contains("collect")) { config = ConfigBuild.buildQueryFrame(devCode); } else { config = ConfigBuild.build433ConfigFrame(devCode, configItem); } config[10] = routeflag;//通信方式 DispatchMessage(code, config); int num = int.Parse(devcode[1]); if (--num > 0) { if (devcode[0].Contains("$")) { redis.ListRightPush<String>(code, devcode[0] + ":" + num.ToString()); } else { redis.ListLeftPush<String>(code, devcode[0] + ":" + num.ToString()); } } Thread.Sleep(interval); } } catch (Exception ex) { Logger.Error("下发配置错误:" + ex.ToString()); } finally { if (concentratorThreadList.Contains(code)) { concentratorThreadList.Remove(code); } } } protected override void OnSessionClosed(CasicSession session, CloseReason reason) { if (session.HubAddr != null) { //集中器离线,给第三方发信息 if (Common.concentratorWithSessionIdMap.ContainsKey(session.HubAddr)) { Logger.Info("集中器离线,移除连接:" + session.HubAddr + "," + session.SessionID); Common.concentratorWithSessionIdMap.Remove(session.HubAddr); } DateTime now = DateTime.Now; DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1)); //当地时区 long timeStamp = (long)(now - startTime).TotalMilliseconds; //相差毫秒数 String logtime = now.ToString("yyyy") + now.ToString("MM") + now.ToString("dd") + now.ToString("HH") + now.ToString("mm") + now.ToString("ss"); String message = JsonConvert.SerializeObject(new Json("Event", "Concentrator", session.HubAddr, new DataJson("ConcentratorOffline", -1, null, logtime), timeStamp)); if (Common.SendMessage(message)) { session.Logger.Info("往第三方发送数据:" + message); } else { session.Logger.Info("未连接上第三方服务器"); } } base.OnSessionClosed(session, reason); } public void DispatchMessage(string devCode, byte[] config) { if (Common.concentratorWithSessionIdMap.ContainsKey(devCode)) { String sessionID = Common.concentratorWithSessionIdMap[devCode]; Logger.Info("集中器设备编号:" + devCode + "," + sessionID); CasicSession s = this.GetSessionByID(sessionID); if (s != null && s.Connected) { //增加CRC校验 String strCrc = StringUtil.To16HexString(String.Format("{0:X}", (int)CodeUtils.CRC16_AD(config))); byte[] btcrc = { CodeUtils.String2Byte(strCrc.Substring(0, 2)), CodeUtils.String2Byte(strCrc.Substring(2, 2)) }; byte[] afcrc = new byte[config.Length + 2]; config.CopyTo(afcrc, 0); btcrc.CopyTo(afcrc, config.Length); Logger.Info("主动下发配置信息:" + BitConverter.ToString(afcrc).Replace("-", "")); s.Send(afcrc, 0, afcrc.Length); } else { Logger.Info("主动下发配置失败,连接不存在或已断开"); } } //foreach (CasicSession session in this.GetAllSessions()) //{ // //可以改进 // session.Logger.Info("集中器设备编号:" + session.HubAddr + "," + session.SessionID); // if (session.HubAddr == devCode && devCode != null) // { // //增加CRC校验 // String strCrc = StringUtil.To16HexString(String.Format("{0:X}", (int)CodeUtils.CRC16_AD(config))); // byte[] btcrc = { CodeUtils.String2Byte(strCrc.Substring(0, 2)), CodeUtils.String2Byte(strCrc.Substring(2, 2)) }; // byte[] afcrc = new byte[config.Length + 2]; // config.CopyTo(afcrc, 0); // btcrc.CopyTo(afcrc, config.Length); // session.Logger.Info("主动下发配置信息:" + BitConverter.ToString(afcrc).Replace("-", "")); // session.Send(afcrc, 0, afcrc.Length); // } //} } } }