public void ClearSubscriptionsClearsSubscriptions() { MqttSubscribeMessage msg = new MqttSubscribeMessage(); msg.Payload.AddSubscription("A/Topic", MqttQos.AtMostOnce); msg.Payload.ClearSubscriptions(); Assert.Equal<int>(0, msg.Payload.Subscriptions.Count); }
public void AddSubscriptionOverExistingSubscriptionUpdatesQos() { MqttSubscribeMessage msg = new MqttSubscribeMessage(); msg.Payload.AddSubscription("A/Topic", MqttQos.AtMostOnce); msg.Payload.AddSubscription("A/Topic", MqttQos.AtLeastOnce); Assert.Equal<MqttQos>(MqttQos.AtLeastOnce, msg.Payload.Subscriptions["A/Topic"]); }
/// <summary> /// Creates a new subscription for the specified topic. /// </summary> /// <typeparam name="T">The type of data the subscription is expected to return.</typeparam> /// <typeparam name="TPayloadConverter">The type of the converter that can convert from bytes to the type T.</typeparam> /// <param name="topic">The topic to subscribe to.</param> /// <param name="qos">The QOS level to subscribe at.</param> /// <returns>An observable that yields messages when they arrive.</returns> private IObservable <MqttReceivedMessage <T> > CreateNewSubscription <T, TPayloadConverter>(string topic, MqttQos qos) where TPayloadConverter : IPayloadConverter <T>, new() { Log.Info(m => m("Creating subscription for topic {0} @ QOS {1}.", topic, qos)); // Get an ID that represents the subscription. We will use this same ID for unsubscribe as well. var msgId = messageIdentifierDispenser.GetNextMessageIdentifier("subscriptions"); // create a new observable that is used to yield messages // that arrive for the topic. var observable = CreateObservableForSubscription(topic, msgId); var sub = new Subscription { Topic = topic, Qos = qos, MessageIdentifier = msgId, CreatedTime = DateTime.Now, Observable = observable, }; pendingSubscriptions.Add(sub.MessageIdentifier, sub); // build a subscribe message for the caller and send it off to the broker. var msg = new MqttSubscribeMessage().WithMessageIdentifier(sub.MessageIdentifier) .ToTopic(sub.Topic) .AtQos(sub.Qos); connectionHandler.SendMessage(msg); return(WrapSubscriptionObservable <T, TPayloadConverter>(topic, sub.Observable)); }
public void MultiTopic() { // double topic Subscribe var expected = new[] { (byte)0x82, (byte)0x10, (byte)0x00, (byte)0x03, (byte)0x00, (byte)0x04, (byte)'f', (byte)'r', (byte)'e', (byte)'d', (byte)0x01, (byte)0x00, (byte)0x04, (byte)'m', (byte)'a', (byte)'r', (byte)'k', (byte)0x02 }; MqttMessage msg = new MqttSubscribeMessage() .ToTopic("fred") .AtQos(MqttQos.AtLeastOnce) .ToTopic("mark") .AtQos(MqttQos.ExactlyOnce) .WithMessageIdentifier(3) .ExpectAcknowledgement(); Console.WriteLine(msg); byte[] actual = MessageSerializationHelper.GetMessageBytes(msg); Assert.Equal<int>(expected.Length, actual.Length); Assert.Equal<byte>(expected[0], actual[0]); // msg type of header Assert.Equal<byte>(expected[1], actual[1]); // remaining length Assert.Equal<byte>(expected[2], actual[2]); // Start of VH: MsgID Byte1 Assert.Equal<byte>(expected[3], actual[3]); // MsgID Byte 2 Assert.Equal<byte>(expected[4], actual[4]); // Topic Length B1 Assert.Equal<byte>(expected[5], actual[5]); // Topic Length B2 Assert.Equal<byte>(expected[6], actual[6]); // f Assert.Equal<byte>(expected[7], actual[7]); // r Assert.Equal<byte>(expected[8], actual[8]); // e Assert.Equal<byte>(expected[9], actual[9]); // d Assert.Equal<byte>(expected[10], actual[10]); // Qos (LeastOnce) Assert.Equal<byte>(expected[11], actual[11]); // Topic Length B1 Assert.Equal<byte>(expected[12], actual[12]); // Topic Length B2 Assert.Equal<byte>(expected[13], actual[13]); // m Assert.Equal<byte>(expected[14], actual[14]); // a Assert.Equal<byte>(expected[15], actual[15]); // r Assert.Equal<byte>(expected[16], actual[16]); // k Assert.Equal<byte>(expected[17], actual[17]); // Qos (ExactlyOnce) }
public void SingleTopic() { // simple single topic Subscribe message var expected = new[] { (byte)0x8A, (byte)0x09, (byte)0x00, (byte)0x02, (byte)0x00, (byte)0x04, (byte)'f', (byte)'r', (byte)'e', (byte)'d', (byte)0x01, }; MqttMessage msg = new MqttSubscribeMessage() .ToTopic("fred") .AtQos(MqttQos.AtLeastOnce) .WithMessageIdentifier(2) .ExpectAcknowledgement() .IsDuplicate(); Console.WriteLine(msg); byte[] actual = MessageSerializationHelper.GetMessageBytes(msg); Assert.Equal<int>(expected.Length, actual.Length); Assert.Equal<byte>(expected[0], actual[0]); // msg type of header Assert.Equal<byte>(expected[1], actual[1]); // remaining length Assert.Equal<byte>(expected[2], actual[2]); // Start of VH: MsgID Byte1 Assert.Equal<byte>(expected[3], actual[3]); // MsgID Byte 2 Assert.Equal<byte>(expected[4], actual[4]); // Topic Length B1 Assert.Equal<byte>(expected[5], actual[5]); // Topic Length B2 Assert.Equal<byte>(expected[6], actual[6]); // f Assert.Equal<byte>(expected[7], actual[7]); // r Assert.Equal<byte>(expected[8], actual[8]); // e Assert.Equal<byte>(expected[9], actual[9]); // d Assert.Equal<byte>(expected[10], actual[10]); // d }
/// <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); }