protected override void Start() { if (null != _mqttServer) { return; } ///相关参数不能为空 if (this.IOServer == null || this.IOCommunication == null) { return; } var optionBuilder = new MqttServerOptionsBuilder().WithConnectionBacklog(1000).WithDefaultEndpointPort(ServerPort); if (!String.IsNullOrEmpty(ServerIP)) { optionBuilder.WithDefaultEndpointBoundIPAddress(IPAddress.Parse(ServerIP)); } var options = optionBuilder.Build(); //连接验证 (options as MqttServerOptions).ConnectionValidator += context => { string clientId = ""; Task.Run(() => { try { ParaPack paraPack = new ParaPack(this.IOCommunication.IO_COMM_PARASTRING); if (context.ClientId.Length < 2) { context.ReturnCode = MqttConnectReturnCode.ConnectionRefusedIdentifierRejected; return; } if (EaableAnonymousAuthentication) { if (!context.Username.Equals(this.UserName)) { context.ReturnCode = MqttConnectReturnCode.ConnectionRefusedBadUsernameOrPassword; return; } if (!context.Password.Equals(this.Password)) { context.ReturnCode = MqttConnectReturnCode.ConnectionRefusedBadUsernameOrPassword; return; } } bool isValidCleint = false; for (int i = 0; i < IODevices.Count; i++) { ParaPack deviceparaPack = new ParaPack(IODevices[i].IO_DEVICE_PARASTRING); clientId = deviceparaPack.GetValue("MQTT连接ID号").Trim(); // 将字符串转换为字符数组 if (clientId.Trim() == context.ClientId.Trim()) { isValidCleint = true; IODevices[i].Tag = clientId.Trim();//标记对应的客户端ID号 } } if (isValidCleint) { context.ReturnCode = MqttConnectReturnCode.ConnectionAccepted; } else { context.ReturnCode = MqttConnectReturnCode.ConnectionRefusedIdentifierRejected; } } catch { context.ReturnCode = MqttConnectReturnCode.ConnectionRefusedIdentifierRejected; } if (string.IsNullOrEmpty(clientId)) { context.ReturnCode = MqttConnectReturnCode.ConnectionRefusedIdentifierRejected; } }); }; _mqttServer = new MqttFactory().CreateMqttServer(); //开始连接 _mqttServer.ClientConnected += (sender, args) => { if (args.ClientId == null || args.ClientId == "") { return; } IO_DEVICE device = this.IODevices.Find(x => x.Tag.ToString().Trim() == args.ClientId.Trim()); if (device == null) { for (int i = 0; i < IODevices.Count; i++) { ParaPack deviceparaPack = new ParaPack(IODevices[i].IO_DEVICE_PARASTRING); string clientId = deviceparaPack.GetValue("MQTT连接ID号").Trim(); // 将字符串转换为字符数组 if (clientId.Trim() == args.ClientId.Trim()) { IODevices[i].Tag = clientId.Trim();//标记对应的客户端ID号 device = IODevices[i]; break; } } } if (device == null) { return; } ParaPack commPack = new ParaPack(this.IOCommunication.IO_COMM_PARASTRING); ParaPack devicePack = new ParaPack(device.IO_DEVICE_PARASTRING); #region 通用MQTT解析 { //客户端连接上后发布订阅数据 List <TopicFilter> topicFilters = new List <TopicFilter>(); device.IO_DEVICE_STATUS = 1; this.DeviceStatus(this.IOServer, IOCommunication, device, null, "1"); string clientId = devicePack.GetValue("MQTT连接ID号").Trim(); // 将字符串转换为字符数组 device.Tag = clientId; if (clientId.Trim() == args.ClientId.Trim()) { TopicFilter topicFilter = new TopicFilter(devicePack.GetValue("数据订阅主题").Trim(), MessageQulity); topicFilters.Add(topicFilter); try { Task.Run(async() => { await _mqttServer.SubscribeAsync(args.ClientId.Trim(), topicFilters); }); } catch (Exception) { this.DeviceException("ERROR=MQTTNet_20006,发布订阅主题失败 "); } } else { this.DeviceException("ERROR=MQTTNet_20006,MQTT ID与设备配置ID不匹配 "); } //定时向客户端发布一个读取数据的订阅 if (commPack.GetValue("接收方式") == "主动") { MQTTTimer cleintMqtt = new MQTTTimer() { ClientID = args.ClientId }; MqttClientTimes.Add(cleintMqtt); cleintMqtt.Timer = new Timer(delegate { if (!cleintMqtt.IsStop) { try { _mqttServer.PublishAsync( new MqttApplicationMessage() { QualityOfServiceLevel = MessageQulity, Retain = false, Topic = devicePack.GetValue("主动请求主题").Trim(), Payload = Encoding.UTF8.GetBytes("{\"uid\":\"" + devicePack.GetValue("设备ID编码").Trim() + "\",\"updatecycle\":\"" + device.IO_DEVICE_UPDATECYCLE + "\",\"topic\":\"" + devicePack.GetValue("数据订阅主题").Trim() + "\"}") } ); ///服务端向客户端发送一个服务器端循环查询数据的周期 _mqttServer.PublishAsync( new MqttApplicationMessage() { QualityOfServiceLevel = MessageQulity, Retain = false, Topic = devicePack.GetValue("循环周期主题").Trim(), Payload = Encoding.UTF8.GetBytes("{\"uid\":\"" + devicePack.GetValue("设备ID编码").Trim() + "\",\"updatecycle\":\"" + device.IO_DEVICE_UPDATECYCLE + "\",\"topic\":\"" + devicePack.GetValue("数据订阅主题").Trim() + "\"}") } ); } catch (Exception) { this.DeviceException("ERROR=MQTTNet_20006,发布订阅主题失败 "); } } }, args, 1000, device.IO_DEVICE_UPDATECYCLE * 1000); } } #endregion }; ///断开连接 _mqttServer.ClientDisconnected += (sender, args) => { Task.Run(() => { if (args.WasCleanDisconnect) { IO_DEVICE device = this.IODevices.Find(x => x.Tag.ToString().Trim() == args.ClientId.Trim()); if (device != null) { device.IO_DEVICE_STATUS = 0; this.DeviceStatus(this.IOServer, IOCommunication, device, null, "0"); } } }); MQTTTimer cleintTimer = MqttClientTimes.Find(x => x.ClientID == args.ClientId); if (cleintTimer != null) { cleintTimer.Close(); MqttClientTimes.Remove(cleintTimer); } }; ///接收到订阅主题的数据数据 _mqttServer.ApplicationMessageReceived += (sender, args) => { if (args.ClientId == null || args.ClientId.Trim() == "") { return; } if (args.ApplicationMessage.Payload == null || args.ApplicationMessage.Payload.Length <= 0) { this.DeviceException("接收的数据为空"); return; } ParaPack commPack = new ParaPack(this.IOCommunication.IO_COMM_PARASTRING); try { Task.Run(() => { string cleintId = args.ClientId.Trim(); //将接收到的数据发送到实际的对应的解析数据库中 List <IO_DEVICE> selects = this.IODevices.FindAll(x => x.Tag.ToString().Trim() == args.ClientId.Trim()); if (selects.Count <= 0) { return; } string strs = ScadaHexByteOperator.UTF8ByteToString(args.ApplicationMessage.Payload); IO_DEVICE device = null; for (int i = 0; i < selects.Count; i++) { ParaPack selePack = new ParaPack(selects[i].IO_DEVICE_PARASTRING); #region CommonMqttJsonObject mqttJsonObject = ScadaHexByteOperator.JsonToObject <CommonMqttJsonObject>(strs); if (mqttJsonObject == null || mqttJsonObject.paras == null || mqttJsonObject.paras.Count <= 0) { this.DeviceException("接收数据对象转换失败了,没有数据" + strs.Count()); this.DeviceException(strs); continue; } string selectUid = selePack.GetValue("设备ID编码"); if (selectUid.Trim() == mqttJsonObject.device.uid.Trim()) { device = selects[i]; break; } #endregion } if (device == null) { return; } device.IO_DEVICE_STATUS = 1; ParaPack paraPack = new ParaPack(device.IO_DEVICE_PARASTRING); #region string deviceUid = paraPack.GetValue("设备ID编码"); if (!string.IsNullOrEmpty(device.IO_DEVICE_PARASTRING) && args.ApplicationMessage.Topic.Trim() == paraPack.GetValue("数据订阅主题").Trim()) { CommonMqttJsonObject mqttJsonObject = ScadaHexByteOperator.JsonToObject <CommonMqttJsonObject>(strs); this.ReceiveData(this.IOServer, IOCommunication, device, args.ApplicationMessage.Payload, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), mqttJsonObject); } #endregion }); } catch { return; } }; ///订阅主题 _mqttServer.ClientSubscribedTopic += (sender, args) => { }; ///取消订阅主题 _mqttServer.ClientUnsubscribedTopic += (sender, args) => { }; _mqttServer.Started += (sender, args) => { this.IOCommunication.IO_COMM_STATUS = 1; }; _mqttServer.Stopped += (sender, args) => { this.IOCommunication.IO_COMM_STATUS = 0; }; _mqttServer.StartAsync(options); ParaPack commpack = new ParaPack(this.IOCommunication.IO_COMM_PARASTRING); this.CommunctionStartChanged(this.IOServer, this.IOServer.SERVER_IP + " " + this.IOServer.SERVER_NAME + "启动服务"); }
protected override IOData Analysis(IO_SERVER server, IO_COMMUNICATION Communication, IO_DEVICE device, IO_PARA para, byte[] datas, DateTime datatime, object sender) { ParaPack commPack = new ParaPack(Communication.IO_COMM_PARASTRING); ParaPack devicePack = new ParaPack(device.IO_DEVICE_PARASTRING); IOData data = new IOData(); data.QualityStamp = QualityStamp.BAD; if (device == null) { return(data); } if (para == null) { return(data); } if (sender == null) { return(data); } if (datas.Length <= 0) { return(data); } if (commPack.GetValue("数据格式") == "江苏协昌环保股份有限公司") { #region 江苏协昌环保股份有限公司 try { ParaPack paraPack = new ParaPack(para.IO_PARASTRING); string deviceUid = devicePack.GetValue("设备识别号").Trim(); data.CommunicationID = Communication.IO_COMM_ID; data.ID = device.IO_DEVICE_ADDRESS; data.ParaName = para.IO_NAME; data.ServerID = server.SERVER_ID; data.Date = DateTime.Now; string str = ScadaHexByteOperator.UTF8ByteToString(datas); MqttJsonObject mqttJsonObject = (MqttJsonObject)sender; if (mqttJsonObject != null && !string.IsNullOrEmpty(deviceUid) && mqttJsonObject.device.uid.Trim() == deviceUid.Trim()) { //由于一次性获取的是所有数据,所以需要解析所有数据 data.QualityStamp = QualityStamp.GOOD; string jsonname = paraPack.GetValue("JSON名称").Trim(); string boardAddress = paraPack.GetValue("版子地址"); string boardIndex = paraPack.GetValue("版子索引号"); string port = paraPack.GetValue("端口号"); string portIndex = paraPack.GetValue("端口索引号"); string DataType = paraPack.GetValue("数据类型"); string valueIndex = paraPack.GetValue("采集值索引号"); if (mqttJsonObject.paras != null) { MqttJsonPara selectObj = mqttJsonObject.paras.Find(x => x.name.Trim() == jsonname.Trim()); if (selectObj != null) { if (selectObj.data != null && selectObj.data.Count > 0) { string date = selectObj.data[0].ToString(); try { ///解析Json数据 DateTime?dateTime = GetDateTime(date); if (dateTime != null) { string pboardAddress = selectObj.data[int.Parse(boardIndex)].ToString(); string pport = selectObj.data[int.Parse(portIndex)].ToString(); string value = selectObj.data[int.Parse(valueIndex)].ToString(); data.QualityStamp = QualityStamp.GOOD; data.ParaValue = value; data.Date = dateTime; } else { data.QualityStamp = QualityStamp.BAD; data.ParaValue = data.QualityStampValue.ToString(); } } catch (Exception emx) { this.DeviceException(emx.Message); data.QualityStamp = QualityStamp.BAD; data.ParaValue = data.QualityStampValue.ToString(); } } } else { data.QualityStamp = QualityStamp.BAD; data.ParaValue = data.QualityStampValue.ToString(); } } } else { data.QualityStamp = QualityStamp.BAD; data.ParaValue = data.QualityStampValue.ToString(); } } catch (Exception emx) { data.QualityStamp = QualityStamp.BAD; data.ParaValue = data.QualityStampValue.ToString(); this.DeviceException(emx.Message); } #endregion } else if (commPack.GetValue("数据格式") == "通用MQTT解析") { #region 通用MQTT解析 try { ParaPack paraPack = new ParaPack(para.IO_PARASTRING); string deviceUid = devicePack.GetValue("设备ID编码").Trim(); data.CommunicationID = Communication.IO_COMM_ID; data.ID = device.IO_DEVICE_ADDRESS; data.ParaName = para.IO_NAME; data.ServerID = server.SERVER_ID; data.Date = DateTime.Now; string str = ScadaHexByteOperator.UTF8ByteToString(datas); CommonMqttJsonObject mqttJsonObject = (CommonMqttJsonObject)sender; if (mqttJsonObject != null && !string.IsNullOrEmpty(deviceUid) && mqttJsonObject.device.uid.Trim() == deviceUid.Trim()) { //由于一次性获取的是所有数据,所以需要解析所有数据 data.QualityStamp = QualityStamp.GOOD; string jsonname = paraPack.GetValue("IO标识").Trim(); string timeIndex = paraPack.GetValue("时间值索引"); string DataType = paraPack.GetValue("数据类型"); string valueIndex = paraPack.GetValue("采集值索引"); if (DataType == "命令参数") { data.QualityStamp = QualityStamp.GOOD; data.ParaValue = data.QualityStampValue.ToString(); return(data); } //采集参数 if (mqttJsonObject.paras != null) { CommonMqttJsonPara selectObj = mqttJsonObject.paras.Find(x => x.name.Trim() == jsonname.Trim()); if (selectObj != null) { if (selectObj.data != null && selectObj.data.Count > 0) { string date = selectObj.data.Count > (int.Parse(timeIndex) + 1)? selectObj.data[int.Parse(timeIndex)].ToString():DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss,f"); try { ///解析Json数据 DateTime?dateTime = GetDateTime(date); if (dateTime != null) { string value = selectObj.data.Count > (int.Parse(valueIndex) + 1) ? selectObj.data[int.Parse(valueIndex)].ToString():"-9999"; data.QualityStamp = value != "-9999"?QualityStamp.GOOD: QualityStamp.BAD; data.ParaValue = value; data.Date = dateTime; } else { data.QualityStamp = QualityStamp.BAD; data.ParaValue = data.QualityStampValue.ToString(); } } catch (Exception emx) { this.DeviceException(emx.Message); data.QualityStamp = QualityStamp.BAD; data.ParaValue = data.QualityStampValue.ToString(); } } } else { data.QualityStamp = QualityStamp.BAD; data.ParaValue = data.QualityStampValue.ToString(); } } } else { data.QualityStamp = QualityStamp.BAD; data.ParaValue = data.QualityStampValue.ToString(); } } catch (Exception emx) { data.QualityStamp = QualityStamp.BAD; data.ParaValue = data.QualityStampValue.ToString(); this.DeviceException(emx.Message); } #endregion } return(data); }