Example #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 + "启动服务");
        }