/// <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); }
/// <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); }