Esempio n. 1
0
        /// <summary>
        /// Registers a new subscription with the subscription manager.
        /// </summary>
        /// <param name="topic"></param>
        /// <param name="qos"></param>
        /// <returns>The subscription message identifier.</returns>
        internal short RegisterSubscription <TPublishDataConverter>(string topic, MqttQos qos)
            where TPublishDataConverter : IPublishDataConverter
        {
            // check we don't have a pending subscription request for the topic.
            var pendingSubs = from ps in pendingSubscriptions.Values
                              where ps.Topic.Equals(topic)
                              select ps;

            if (pendingSubs.Count <Subscription>() > 0)
            {
                throw new ArgumentException("There is already a pending subscription for this topic");
            }

            // no pending subscription, if we already have a subscription then throw it back out as well
            if (subscriptions.ContainsKey(topic))
            {
                // TODO: we might want to treat this as an ignore/silent confirm because they will be receiving messages for the topic already
                throw new ArgumentException("You are already subscribed for this topic");
            }

            // Add a pending subscription...
            Subscription sub = new Subscription()
            {
                Topic             = topic,
                Qos               = qos,
                MessageIdentifier = MessageIdentifierDispenser.GetNextMessageIdentifier("subscriptions"),
                CreatedTime       = DateTime.Now,
                DataProcessor     = Activator.CreateInstance <TPublishDataConverter>()
            };

            pendingSubscriptions.Add(sub.MessageIdentifier, sub);

            // build a subscribe message for the caller.
            MqttSubscribeMessage msg = new MqttSubscribeMessage()
                                       .WithMessageIdentifier(sub.MessageIdentifier)
                                       .ToTopic(sub.Topic)
                                       .AtQos(sub.Qos);

            connectionHandler.SendMessage(msg);
            return(msg.VariableHeader.MessageIdentifier);
        }
Esempio n. 2
0
        /// <summary>
        /// Publish a message to the broker on the specified topic.
        /// </summary>
        /// <param name="topic">The topic to send the message to.</param>
        /// <param name="payload">The message to send.</param>
        /// <returns>The message identifier assigned to the message.</returns>
        public short Publish <TDataConverter>(string topic, MqttQos qualityOfService, object data)
            where TDataConverter : IPublishDataConverter
        {
            short msgID = MessageIdentifierDispenser.GetNextMessageIdentifier(String.Format("Topic:{0}", topic));

            IPublishDataConverter converter = GetPublishDataConverter <TDataConverter>();

            MqttPublishMessage msg = new MqttPublishMessage()
                                     .ToTopic(topic)
                                     .WithMessageIdentifier(msgID)
                                     .WithQos(qualityOfService)
                                     .PublishData(converter.ConvertToBytes(data));

            // QOS level 1 or 2 messages need to be saved so we can do the ack processes
            if (qualityOfService == MqttQos.AtLeastOnce || qualityOfService == MqttQos.ExactlyOnce)
            {
                publishedMessages.Add(msgID, msg);
            }

            connectionHandler.SendMessage(msg);

            return(msgID);
        }