예제 #1
0
        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 + "启动服务");
        }
예제 #2
0
        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);
        }