예제 #1
0
        private void RouteOnTheQoSLevelOfTheSubscriber(string topic)
        {
            MqttMsgPublish publish = publishQueue[topic].Dequeue();
            //var connectedClients = MqttServer.GetConnectedClientIds();
            var connectedClients     = PacketManager.GetConnectedClientIds();
            var subscriptionsByTopic = subscriptionManager.GetSubscriptionsByTopic(publish.Topic);
            var subscriptions        = subscriptionsByTopic != null?subscriptionsByTopic.Where(s => connectedClients.Contains(s.ClientId)) : null;

            if (subscriptions != null)
            {
                foreach (var sub in subscriptions)
                {
                    if (sub.QosLevel == 0x00 && publish.QosLevel > MqttMsgBase.QOS_LEVEL_AT_MOST_ONCE)
                    {
                        MqttMsgPublish pub = MqttMsgPublish.Parse(publish.GetBytes());
                        pub.QosLevel = MqttMsgBase.QOS_LEVEL_AT_MOST_ONCE;
                        RouteOnQoS(pub, sub);
                    }
                    else if (sub.QosLevel == 0x01 && publish.QosLevel > MqttMsgBase.QOS_LEVEL_AT_LEAST_ONCE)
                    {
                        MqttMsgPublish pub = MqttMsgPublish.Parse(publish.GetBytes());
                        pub.QosLevel = MqttMsgBase.QOS_LEVEL_AT_LEAST_ONCE;
                        RouteOnQoS(pub, sub);
                    }
                    else
                    {
                        RouteOnQoS(publish, sub);
                    }
                }
            }
        }
예제 #2
0
 /// <summary>
 /// Delivers to the subscribers with qos 0 of the publish topic the publish message
 /// </summary>
 /// <param name="sender"></param>
 /// <param name="publish"></param>
 private void ManageQoS0(MqttMsgPublish publish, Subscription subscription)
 {
     try
     {
         //MqttServer.Instance.Send(subscription.ClientId, publish.GetBytes());
         OnPacketReadyToBeSent(subscription.ClientId, publish.GetBytes());
     }
     catch (Exception)
     {
         throw;
     }
 }
예제 #3
0
        /// <summary>
        /// Publish a message to the broker
        /// </summary>
        /// <param name="topic">Message topic</param>
        /// <param name="message">Message data (payload)</param>
        /// <param name="qosLevel">QoS Level</param>
        /// <param name="retain">Retain flag</param>
        /// <returns>Message Id related to PUBLISH message</returns>
        public ushort Publish(string topic, byte[] message,
                              byte qosLevel = MqttMsgBase.QOS_LEVEL_AT_MOST_ONCE,
                              bool retain   = false)
        {
            ushort messageId    = 0;
            int    attempts     = 0;
            bool   acknowledged = false;

            MqttMsgPublish publish =
                new MqttMsgPublish(topic, message, false, qosLevel, retain);

            // based on QoS level, the messages flow between client and broker changes
            switch (qosLevel)
            {
            // QoS Level 0, no answer from broker
            case MqttMsgBase.QOS_LEVEL_AT_MOST_ONCE:

                this.Send(publish.GetBytes());
                break;

            // QoS Level 1, waiting for PUBACK message from broker
            case MqttMsgBase.QOS_LEVEL_AT_LEAST_ONCE:

                attempts     = 0;
                acknowledged = false;

                do
                {
                    MqttMsgPuback puback = null;
                    try
                    {
                        // try publish
                        puback       = (MqttMsgPuback)this.SendReceive(publish.GetBytes());
                        acknowledged = true;
                    }
                    catch (MqttTimeoutException)
                    {
                        // no PUBACK message received in time, retry with duplicate flag
                        attempts++;
                        publish.DupFlag = true;

                        // delay before retry
                        if (attempts < MQTT_ATTEMPTS_RETRY)
                        {
                            Thread.Sleep(MQTT_DELAY_RETRY);
                        }
                    }
                } while ((attempts < MQTT_ATTEMPTS_RETRY) && !acknowledged);

                if (acknowledged)
                {
                    messageId = publish.MessageId;
                }

                break;

            // QoS Level 2, waiting for PUBREC message from broker,
            // send PUBREL message and waiting for PUBCOMP message from broker
            case MqttMsgBase.QOS_LEVEL_EXACTLY_ONCE:

                attempts     = 0;
                acknowledged = false;

                do
                {
                    MqttMsgPubrec pubrec = null;
                    try
                    {
                        // try publish
                        pubrec       = (MqttMsgPubrec)this.SendReceive(publish.GetBytes());
                        acknowledged = true;
                    }
                    catch (MqttTimeoutException)
                    {
                        // no PUBREC message received in time, retry with duplicate flag
                        attempts++;
                        publish.DupFlag = true;

                        // delay before retry
                        if (attempts < MQTT_ATTEMPTS_RETRY)
                        {
                            Thread.Sleep(MQTT_DELAY_RETRY);
                        }
                    }
                } while ((attempts < MQTT_ATTEMPTS_RETRY) && !acknowledged);

                // first phase ok
                if (acknowledged)
                {
                    attempts     = 0;
                    acknowledged = false;

                    do
                    {
                        // set publish message identifier into PUBREL message
                        MqttMsgPubrel pubrel = new MqttMsgPubrel();
                        pubrel.MessageId = publish.MessageId;

                        MqttMsgPubcomp pubcomp = null;
                        try
                        {
                            // try send PUBREL message
                            pubcomp      = (MqttMsgPubcomp)this.SendReceive(pubrel.GetBytes());
                            acknowledged = true;
                        }
                        catch (MqttTimeoutException)
                        {
                            // no PUBCOMP message received in time, retry with duplicate flag
                            attempts++;
                            pubrel.DupFlag = true;

                            // delay before retry
                            if (attempts < MQTT_ATTEMPTS_RETRY)
                            {
                                Thread.Sleep(MQTT_DELAY_RETRY);
                            }
                        }
                    } while ((attempts < MQTT_ATTEMPTS_RETRY) && !acknowledged);

                    if (acknowledged)
                    {
                        messageId = publish.MessageId;
                    }
                }
                break;

            default:
                throw new MqttClientException(MqttClientErrorCode.QosNotAllowed);
            }

            return(messageId);
        }