Beispiel #1
0
 public void OnMqttMsgPublishReceived(MqttMsgPublish msg)
 {
     if (this.ConnectionManager != null)
     {
         this.ConnectionManager.OnMqttMsgPublishReceived(this, msg);
     }
 }
 public void OnMqttMsgPublishReceived(MqttMsgPublish msg)
 {
     if (ProcessingManager != null)
     {
         ProcessingManager.OnMqttMsgPublishReceived(this, msg);
     }
 }
        public void Publish(MqttMsgPublish publish)
        {
            sessionManager.AddInflightMessage(publish);

            switch (publish.QosLevel)
            {
            case MqttMsgBase.QOS_LEVEL_AT_MOST_ONCE:
            {
                CrestronLogger.WriteToLog("MQTTPUBLISHERMANAGER - RouteOnQoS - Routing qos0 message", 5);
                ManageQoS0(publish);
                break;
            }

            case MqttMsgBase.QOS_LEVEL_AT_LEAST_ONCE:
            {
                CrestronLogger.WriteToLog("MQTTPUBLISHERMANAGER - RouteOnQoS - Routing qos1 message", 5);
                ManageQoS1(publish);
                break;
            }

            case MqttMsgBase.QOS_LEVEL_EXACTLY_ONCE:
            {
                CrestronLogger.WriteToLog("MQTTPUBLISHERMANAGER - RouteOnQoS - Routing qos2 message", 5);
                ManageQoS2(publish);
                break;
            }

            default:
                break;
            }
        }
Beispiel #4
0
        public void PublishAdvancedBinaryDecodeTestv5()
        {
            // Arrange
            byte[] encodedCorrect = new byte[] { 109, 0, 19, 116, 104, 105, 115, 116, 111, 112, 105, 99, 47, 115, 111, 109, 101, 116, 104, 105, 110,
                                                 103, 0, 42, 79, 2, 0, 0, 48, 57, 35, 0, 33, 8, 0, 14, 114, 101, 115, 112, 111, 110, 115, 101, 32, 116, 111,
                                                 112, 105, 99, 9, 0, 6, 1, 2, 3, 4, 5, 6, 38, 0, 3, 79, 110, 101, 0, 4, 112, 114, 111, 112, 38, 0, 6, 115, 101,
                                                 99, 111, 110, 100, 0, 8, 112, 114, 111, 112, 101, 114, 116, 121, 11, 254, 255, 255, 127, 3, 0, 6, 98, 105,
                                                 110, 97, 114, 121, 6, 5, 4, 3, 2, 1 };
            MokChannel mokChannel = new(encodedCorrect);
            // Act
            MqttMsgPublish publish = MqttMsgPublish.Parse(60, MqttProtocolVersion.Version_5, mokChannel);

            // Assert
            Assert.Equal(Topic, publish.Topic);
            Assert.Equal(MessageId, publish.MessageId);
            Assert.Equal(new byte[] { 6, 5, 4, 3, 2, 1 }, publish.Message);
            Assert.Equal((byte)MqttQoSLevel.ExactlyOnce, (byte)publish.QosLevel);
            Assert.Equal(true, publish.DupFlag);
            Assert.Equal(false, publish.Retain);
            Assert.Equal(publish.ContentType, "binary");
            Assert.Equal(publish.IsPayloadUTF8, false);
            Assert.Equal(publish.SubscriptionIdentifier, 268435454);
            Assert.Equal(publish.UserProperties.Count, 2);
            var prop = new UserProperty("One", "prop");

            Assert.Equal(((UserProperty)publish.UserProperties[0]).Name, prop.Name);
            Assert.Equal(((UserProperty)publish.UserProperties[0]).Value, prop.Value);
            prop = new UserProperty("second", "property");
            Assert.Equal(((UserProperty)publish.UserProperties[1]).Name, prop.Name);
            Assert.Equal(((UserProperty)publish.UserProperties[1]).Value, prop.Value);
            Assert.Equal(publish.CorrelationData, new byte[] { 1, 2, 3, 4, 5, 6 });
            Assert.Equal(publish.ResponseTopic, "response topic");
            Assert.Equal(publish.TopicAlias, (ushort)33);
            Assert.Equal(publish.MessageExpiryInterval, 12345);
        }
Beispiel #5
0
 public static void CheckForAndSetRetainedMessage(MqttMsgPublish publish)
 {
     if (publish.Retain)
     {
         // retained message already exists for the topic
         if (RetainedMessages.ContainsKey(publish.Topic))
         {
             // if empty message, remove current retained message
             if (publish.Message.Length == 0)
             {
                 MqttMsgPublish oldRetained;
                 RetainedMessages.TryRemove(publish.Topic, out oldRetained);
             }
             else
             {
                 // set new retained message for the topic
                 RetainedMessages[publish.Topic] = publish;
             }
         }
         else
         {
             // add new topic with related retained message
             RetainedMessages.TryAdd(publish.Topic, publish);
         }
     }
 }
Beispiel #6
0
 private void CheckRetain(MqttMsgPublish publish)
 {
     if (publish.Retain)
     {
         // retained message already exists for the topic
         if (retainedMessages.ContainsKey(publish.Topic))
         {
             // if empty message, remove current retained message
             if (publish.Message.Length == 0)
             {
                 retainedMessages.Remove(publish.Topic);
             }
             // set new retained message for the topic
             else
             {
                 retainedMessages[publish.Topic] = publish;
             }
         }
         else
         {
             // add new topic with related retained message
             retainedMessages.Add(publish.Topic, publish);
         }
     }
 }
Beispiel #7
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);
                    }
                }
            }
        }
        /// <summary>
        /// Publish message
        /// </summary>
        /// <param name="publish">Message to publish</param>
        public void Publish(MqttMsgPublish publish)
        {
            retainedMessageManager.CheckForAndSetRetainedMessage(publish);

            // enqueue
            publishQueue.Add(publish);
            sessionsPublishQueue.Add(publish);
        }
Beispiel #9
0
        public void Publish(string topic, string value, uint retain)
        {
            byte[]         payload = Encoding.ASCII.GetBytes(value);
            MqttMsgPublish msg     = MsgBuilder.BuildPublish(topic, false, (retain > 0), payload, GetNewPacketIdentifier());

            publisherManager.Publish(msg);
            FreePacketIdentifier(msg.MessageId); // this can be done automatically as long as we only publish at QoS 0
        }
        /// <summary>
        /// Publish message
        /// </summary>
        /// <param name="publish">Message to publish</param>
        public void Publish(MqttMsgPublish publish)
        {
            RetainedMessageManager.CheckForAndSetRetainedMessage(publish);

            // enqueue
            this.publishQueue.Add(publish);
            this.sessionPublishQueue.Add(publish);
        }
Beispiel #11
0
 /// <summary>
 /// Wrapper method for raising PUBLISH message received event
 /// </summary>
 /// <param name="publish">PUBLISH message received</param>
 private void OnMqttMsgPublishReceived(MqttMsgPublish publish)
 {
     if (this.MqttMsgPublishReceived != null)
     {
         this.MqttMsgPublishReceived(this,
                                     new MqttMsgPublishEventArgs(publish.Topic, publish.Message, publish.QosLevel, publish.Retain));
     }
 }
 private void HandlePUBLISHType(uint clientIndex, MqttMsgPublish packet)
 {
     try
     {
         publishManager.Publish(packet);
     }
     catch (Exception)
     {
         throw;
     }
 }
        /// <summary>
        /// Publish a message asynchronously
        /// </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 static ushort Publish(MqttClientConnection clientConnection, string topic, byte[] message, byte qosLevel, bool retain)
        {
            MqttMsgPublish publish = new MqttMsgPublish(topic, message, false, qosLevel, retain);

            publish.MessageId = clientConnection.GetMessageId();

            // enqueue message to publish into the inflight queue
            EnqueueInflight(clientConnection, publish, MqttMsgFlow.ToPublish);

            return(publish.MessageId);
        }
        public void Publish(string topic, string value)
        {
            byte[]         payload = Encoding.ASCII.GetBytes(value);
            MqttMsgPublish msg     = MsgBuilder.BuildPublish(topic, false, (byte)this.PublishQoSLevel, Retain, payload, GetNewPacketIdentifier());

            publisherManager.Publish(msg);
            if (this.PublishQoSLevel == 0x00)
            {
                FreePacketIdentifier(msg.MessageId);
            }
        }
Beispiel #15
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;
     }
 }
Beispiel #16
0
        void Client_MqttMsgPublishReceived(object sender, MqttMsgPublishEventArgs e)
        {
            MqttClient client = (MqttClient)sender;

            // create PUBLISH message to publish
            // [v3.1.1] DUP flag from an incoming PUBLISH message is not propagated to subscribers
            //          It should be set in the outgoing PUBLISH message based on transmission for each subscriber
            MqttMsgPublish publish = new MqttMsgPublish(e.Topic, e.Message, false, e.QosLevel, e.Retain);

            // publish message through publisher manager
            this.publisherManager.Publish(publish);
        }
Beispiel #17
0
        public static MqttMsgPublish BuildPublish(string topic, bool dupFlag, byte qosLevel, bool retain, byte[] message, ushort messageId)
        {
            MqttMsgPublish publish = new MqttMsgPublish();

            publish.DupFlag   = dupFlag;
            publish.QosLevel  = qosLevel;
            publish.Retain    = retain;
            publish.Topic     = topic;
            publish.MessageId = messageId;
            publish.Message   = message;
            return(publish);
        }
Beispiel #18
0
        public static MqttMsgPublish BuildPublish(string topic, bool dupFlag, bool retain, byte[] message, ushort messageId)
        {
            MqttMsgPublish publish = new MqttMsgPublish();

            publish.DupFlag   = dupFlag;
            publish.QosLevel  = 0x00; // publishing at QoS 0 is all that is currently supported
            publish.Retain    = retain;
            publish.Topic     = topic;
            publish.MessageId = messageId;
            publish.Message   = message;
            return(publish);
        }
        public void OnMqttMsgPublishReceived(MqttClientConnection clientConnection, MqttMsgPublish msg)
        {
            if (uacManager.AuthenticatePublish(clientConnection, msg.Topic))
            {
                // create PUBLISH message to publish
                // [v3.1.1] DUP flag from an incoming PUBLISH message is not propagated to subscribers
                //          It should be set in the outgoing PUBLISH message based on transmission for each subscriber
                MqttMsgPublish publish = new MqttMsgPublish(msg.Topic, msg.Message, false, msg.QosLevel, msg.Retain);

                // publish message through publisher manager
                this.publishManager.Publish(publish);
            }
        }
Beispiel #20
0
        /// <summary>
        /// Close a client
        /// </summary>
        /// <param name="client">Client to close</param>
        private void CloseClient(MqttClient client)
        {
            if (PreClients.Contains(client))
            {
                // close the client
                client.Close();

                // remove client from the collection
                this.PreClients.Remove(client);
            }
            else if (this.Clients.ContainsKey(client.ClientId))
            {
                // if client is connected and it has a will message
                if (!client.IsConnected && client.WillFlag)
                {
                    // create the will PUBLISH message
                    MqttMsgPublish publish =
                        new MqttMsgPublish(client.WillTopic, Encoding.UTF8.GetBytes(client.WillMessage), false, client.WillQosLevel, false);

                    // publish message through publisher manager
                    this.publisherManager.Publish(publish);
                }

                // if not clean session
                if (!client.CleanSession)
                {
                    List <MqttSubscription> subscriptions = this.subscriberManager.GetSubscriptionsByClient(client.ClientId);

                    if ((subscriptions != null) && (subscriptions.Count > 0))
                    {
                        this.sessionManager.SaveSession(client.ClientId, client.Session, subscriptions);

                        // TODO : persist client session if broker close
                    }
                }

                // delete client from runtime subscription
                this.subscriberManager.Unsubscribe(client);

                // close the client
                client.Close();

                // remove client from the collection
                this.Clients.Remove(client.ClientId);
            }
        }
        void Client_MqttMsgPublishReceived(object sender, MqttMsgPublishEventArgs e)
        {
            MqttClient client = (MqttClient)sender;

            // create PUBLISH message to publish
            // [v3.1.1] DUP flag from an incoming PUBLISH message is not propagated to subscribers
            //          It should be set in the outgoing PUBLISH message based on transmission for each subscriber
            MqttMsgPublish publish = new MqttMsgPublish(e.Topic, e.Message, false, e.QosLevel, e.Retain);

            string payload = Encoding.ASCII.GetString(e.Message);

            Console.WriteLine("Publish Received: [{0},{1}]", e.Topic, payload);
            SDCommandHandler.HandleCommand(payload);

            // publish message through publisher manager
            this.publisherManager.Publish(publish);
        }
Beispiel #22
0
        public void PublishBasicDecodeTestv311()
        {
            // Arrange
            byte[] encodedCorrect = new byte[] { 47, 0, 19, 116, 104, 105, 115, 116, 111, 112, 105, 99, 47, 115, 111, 109, 101, 116, 104, 105, 110,
                                                 103, 0, 42, 84, 104, 105, 115, 32, 105, 115, 32, 97, 32, 115, 116, 114, 105, 110, 103, 32, 109, 101, 115,
                                                 115, 97, 103, 101 };
            MokChannel mokChannel = new(encodedCorrect);
            // Act
            MqttMsgPublish publish = MqttMsgPublish.Parse(60, MqttProtocolVersion.Version_3_1_1, mokChannel);

            // Assert
            Assert.Equal(Topic, publish.Topic);
            Assert.Equal(MessageId, publish.MessageId);
            Assert.Equal(MessageString, Encoding.UTF8.GetString(publish.Message, 0, publish.Message.Length));
            Assert.Equal((byte)MqttQoSLevel.ExactlyOnce, (byte)publish.QosLevel);
            Assert.Equal(true, publish.DupFlag);
            Assert.Equal(false, publish.Retain);
        }
        public void OnConnectionClosed(MqttClientConnection clientConnection)
        {
            // if client is connected
            MqttClientConnection connectedClient;

            if (clientConnection.IsConnected && MqttBroker.TryRemoveClientConnection(clientConnection.ClientId, out connectedClient))
            {
                // client has a will message
                if (clientConnection.WillFlag)
                {
                    // create the will PUBLISH message
                    MqttMsgPublish publish = new MqttMsgPublish(clientConnection.WillTopic, Encoding.UTF8.GetBytes(clientConnection.WillMessage), false, clientConnection.WillQosLevel, false);

                    // publish message through publisher manager
                    this.publishManager.Publish(publish);
                }

                // if not clean session
                if (!clientConnection.CleanSession)
                {
                    List <MqttSubscription> subscriptions = clientConnection.Subscriptions.Values.ToList();

                    if (subscriptions.Count > 0)
                    {
                        MqttSessionManager.SaveSession(clientConnection.ClientId, clientConnection.Session, subscriptions);

                        // TODO : persist client session if broker close
                    }
                }

                foreach (var topic in clientConnection.Subscriptions.Keys)
                {
                    // delete client from runtime subscription
                    MqttSubscriberManager.Unsubscribe(topic, clientConnection);
                }

                // close the client
                CloseClientConnection(clientConnection);
                clientConnectionManager.ReturnConnection(clientConnection);
                Interlocked.Decrement(ref numberOfConnectedClients);
            }
        }
Beispiel #24
0
 internal void Publish(MqttMsgPublish packet)
 {
     CheckRetain(packet);
     packet.Retain = false; //MQTT-3.3.1-9
     if (!publishQueue.ContainsKey(packet.Topic))
     {
         publishQueue.Add(packet.Topic, new Queue <MqttMsgPublish>());
     }
     publishQueue[packet.Topic].Enqueue(packet);
     RouteOnTheQoSLevelOfTheSubscriber(packet.Topic);
     lock (publishQueue)
     {
         if (publishQueue.ContainsKey(packet.Topic))
         {
             if (publishQueue[packet.Topic].Count == 0)
             {
                 publishQueue.Remove(packet.Topic);
             }
         }
     }
 }
        private void HandlePUBLISHType(MqttMsgPublish publish)
        {
            try
            {
                switch (publish.QosLevel)
                {
                case MqttMsgBase.QOS_LEVEL_AT_MOST_ONCE:
                {
                    CrestronLogger.WriteToLog("MQTTCLIENT - HandlePUBLISHType - Routing qos0 message", 5);
                    string publishPayload = System.Text.Encoding.ASCII.GetString(publish.Message, 0, publish.Message.Length);
                    OnMessageArrived(publish.Topic, PayloadMapper.Map(publishPayload));
                    break;
                }

                case MqttMsgBase.QOS_LEVEL_AT_LEAST_ONCE:
                {
                    CrestronLogger.WriteToLog("MQTTCLIENT - HandlePUBLISHType - Routing qos1 message", 5);
                    string publishPayload = System.Text.Encoding.ASCII.GetString(publish.Message, 0, publish.Message.Length);
                    Send(MsgBuilder.BuildPubAck(publish.MessageId));
                    OnMessageArrived(publish.Topic, PayloadMapper.Map(publishPayload));
                    break;
                }

                case MqttMsgBase.QOS_LEVEL_EXACTLY_ONCE:
                {
                    CrestronLogger.WriteToLog("MQTTCLIENT - HandlePUBLISHType - Routing qos2 message", 5);
                    //ManageQoS2(publish);
                    break;
                }

                default:
                    break;
                }
                //TODO: Raise MessageArrived event , handle the necessary responses with the publisher manager.
            }
            catch (ArgumentException e)
            {
                OnErrorOccured(e.Message);
            }
        }
Beispiel #26
0
 protected void OnClientDisconnected(MqttClient client, bool withDisconnectPacket)
 {
     try
     {
         if (!withDisconnectPacket && client.WillFlag)
         {
             MqttMsgPublish publish = MsgBuilder.BuildPublish(client.WillTopic, false, client.WillQosLevel, client.WillRetain, Encoding.ASCII.GetBytes(client.WillMessage), GetNewPacketIdentifier());
             //Send(client.ClientIndex, publish.GetBytes());
             OnPacketReceived(client.ClientIndex, publish, client.IsWebSocketClient);
         }
         else if (withDisconnectPacket)
         {
             SessionManager.Destroy(client.ClientId);
             client.IsConnected = false;
         }
     }
     catch (Exception e)
     {
         CrestronLogger.WriteToLog("MQTTSERVER - OnClientDisconnected , error message : " + e.Message, 8);
         CrestronLogger.WriteToLog("MQTTSERVER - OnClientDisconnected , error STACK TRACE : " + e.StackTrace, 8);
     }
 }
Beispiel #27
0
        void Client_MqttMsgPublishReceived(object sender, MqttMsgPublishEventArgs e)
        {
            MqttClient client = (MqttClient)sender;

            // create PUBLISH message to publish
            // [v3.1.1] DUP flag from an incoming PUBLISH message is not propagated to subscribers
            //          It should be set in the outgoing PUBLISH message based on transmission for each subscriber
            MqttMsgPublish publish = new MqttMsgPublish(e.Topic, e.Message, false, e.QosLevel, e.Retain);

            // publish message through publisher manager
            this.publisherManager.Publish(publish);

            //signal
            EventHandler <MqttClientEventArgs> handler = DidRecievePublishMessageFromClient;

            if (handler != null)
            {
                MqttClientEventArgs arg = new MqttClientEventArgs();
                arg.Client = client;
                handler(this, arg);
            }
        }
Beispiel #28
0
        void Client_MqttMsgPublishReceived(object sender, MqttMsgPublishEventArgs e)
        {
            MqttClient client = (MqttClient)sender;

            // Fire event on threadpool so that a host application can directly access published messages.
            var mqttPublihForEvent = new MqttMsgPublish(e.Topic, e.Message, false, e.QosLevel, e.Retain);
            var messageEvent       = new KeyValuePair <string, MqttMsgPublish>(client.ClientId, mqttPublihForEvent);

            Task.Run(() =>
            {
                Interlocked.CompareExchange(ref MessagePublished, null, null)?.Invoke(messageEvent);
            });

            // create PUBLISH message to publish
            // [v3.1.1] DUP flag from an incoming PUBLISH message is not propagated to subscribers
            //          It should be set in the outgoing PUBLISH message based on transmission for each subscriber
            MqttMsgPublish publish = new MqttMsgPublish(e.Topic, e.Message, false, e.QosLevel, e.Retain);


            // publish message through publisher manager
            this.publisherManager.Publish(publish);
        }
 public void CheckForAndSetRetainedMessage(MqttMsgPublish publish)
 {
     if (publish.Retain)
     {
         if (RetainedMessages.ContainsKey(publish.Topic))
         {
             if (publish.Message.Length == 0)
             {
                 MqttMsgPublish oldRetained;
                 RetainedMessages.TryRemove(publish.Topic, out oldRetained);
             }
             else
             {
                 // set new retained message for the topic
                 RetainedMessages[publish.Topic] = publish;
             }
         }
         else
         {
             RetainedMessages.TryAdd(publish.Topic, publish);
         }
     }
 }
        /// <summary>
        /// Publish message
        /// </summary>
        /// <param name="publish">Message to publish</param>
        public void Publish(MqttMsgPublish publish)
        {
            if (publish.Retain)
            {
                lock (this.retainedMessages)
                {
                    // retained message already exists for the topic
                    if (retainedMessages.ContainsKey(publish.Topic))
                    {
                        // if empty message, remove current retained message
                        if (publish.Message.Length == 0)
                        {
                            retainedMessages.Remove(publish.Topic);
                        }
                        // set new retained message for the topic
                        else
                        {
                            retainedMessages[publish.Topic] = publish;
                        }
                    }
                    else
                    {
                        // add new topic with related retained message
                        retainedMessages.Add(publish.Topic, publish);
                    }
                }
            }

            // enqueue
            lock (this.publishQueue)
            {
                this.publishQueue.Enqueue(publish);
            }

            // unlock thread for sending messages to the subscribers
            this.publishQueueWaitHandle.Set();
        }