Example #1
0
        public void MultiTopic()
        {
            // double topic unsubscribe
            var expected = new[]
            {
                (byte)0xA2,
                (byte)0x0E,
                (byte)0x00,
                (byte)0x03,
                (byte)0x00,
                (byte)0x04,
                (byte)'f',
                (byte)'r',
                (byte)'e',
                (byte)'d',
                (byte)0x00,
                (byte)0x04,
                (byte)'m',
                (byte)'a',
                (byte)'r',
                (byte)'k',
            };

            MqttMessage msg = new MqttUnsubscribeMessage()
                .FromTopic("fred")
                .FromTopic("mark")
                .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]); // Topic Length B1
            Assert.Equal<byte>(expected[11], actual[11]); // Topic Length B2
            Assert.Equal<byte>(expected[12], actual[12]); // f
            Assert.Equal<byte>(expected[13], actual[13]); // r
            Assert.Equal<byte>(expected[14], actual[14]); // e
            Assert.Equal<byte>(expected[15], actual[15]); // d
        }
Example #2
0
        public void ClearSubscriptions()
        {
            MqttUnsubscribeMessage msg = new MqttUnsubscribeMessage()
                .FromTopic("fred")
                .FromTopic("mark")
                .WithMessageIdentifier(3)
                .ExpectAcknowledgement();
            Console.WriteLine(msg);

            Assert.Equal<int>(2, msg.Payload.Subscriptions.Count);

            msg.Payload.ClearSubscriptions();

            Assert.Equal<int>(0, msg.Payload.Subscriptions.Count);
        }
Example #3
0
        /// <summary>
        ///     Creates an observable for a subscription.
        /// </summary>
        /// <param name="subscriptionTopic">The topic to the obserbable should read messages on.</param>
        /// <param name="msgId">The messgeid assigned to the subscription.</param>
        /// <returns>An observable that yields a byte array for each message that arrives on a topoc.</returns>
        private IObservable <MqttReceivedMessage <byte[]> > CreateObservableForSubscription(SubscriptionTopic subscriptionTopic, short msgId)
        {
            var observable = Observable.Create <MqttReceivedMessage <byte[]> >(observer => {
                Log.Info(m => m("Creating underlying core observable for topoc {0}.", subscriptionTopic));

                // Listen for payload messages and when they arrive for our topoc
                // publish them onto the observable.
                var msgPubObservable
                    = Observable.FromEventPattern <PublishEventArgs>(h => publishingManager.MessageReceived += h,
                                                                     h => publishingManager.MessageReceived -= h);
                var msgPubSub = msgPubObservable
                                .Where(ep => subscriptionTopic.Matches(ep.EventArgs.Topic))
                                .Select(ep => ep.EventArgs)
                                .Subscribe(eventArgs => {
                    try {
                        // we use the messages topic name here so that if the
                        // matched subscription was a wildcard, we give the
                        // consumer the actual topic the message was published
                        // for, not the original wildcard subscription topic.
                        observer.OnNext(new MqttReceivedMessage <byte[]>(eventArgs.Topic.ToString(),
                                                                         eventArgs.PublishMessage.Payload.Message.ToArray()));
                    } catch (Exception ex) {
                        Log.Error(m => m("Error while publishing message to observer for topic {0}.", eventArgs.Topic.ToString()), ex);
                    }
                });

                // Unsubscribe from the topoc on the server,
                return(Disposable.Create(() => {
                    Log.Info(m => m("Last subscriber gone for topic '{0}', unsubscribing on broker.", subscriptionTopic));

                    // stop processing publish messages for this topoc received by thethe publishing manager.
                    msgPubSub.Dispose();

                    // build a unsubscribe message for the caller and send it off to the broker.
                    var unsubscribeMsg = new MqttUnsubscribeMessage()
                                         .WithMessageIdentifier(messageIdentifierDispenser.GetNextMessageIdentifier("unsubscriptions"))
                                         .WithMessageIdentifier(msgId)
                                         .FromTopic(subscriptionTopic.ToString());
                    connectionHandler.SendMessage(unsubscribeMsg);
                }));
            });

            // Publish and refcount so we can share the single subscription amongst all
            // subscribers and dispose automatically when everyone has disposed their
            // subscriptions.
            return(observable.Publish()
                   .RefCount());
        }
Example #4
0
        /// <summary>
        ///     Creates an observable for a subscription.
        /// </summary>
        /// <param name="topic">The topic to create the observable for.</param>
        /// <param name="msgId">The messgeid assigned to the subscription</param>
        /// <returns>An observable that yields a byte array for each message that arrives on a topic.</returns>
        private IObservable <byte[]> CreateObservableForSubscription(string topic, short msgId)
        {
            var observable = Observable.Create((IObserver <byte[]> observer) => {
                Log.Info(m => m("Creating underlying core observable for topic {0}.", topic));

                // Listen for payload messages and when they arrive for our topic
                // publish them onto the observable.
                var msgPubObservable
                    = Observable.FromEventPattern <PublishEventArgs>(h => publishingManager.MessageReceived += h,
                                                                     h => publishingManager.MessageReceived -= h);
                var msgPubSub = msgPubObservable
                                .Where(ep => topic.Equals(ep.EventArgs.PublishMessage.VariableHeader.TopicName))
                                .Select(ep => ep.EventArgs.PublishMessage)
                                .Subscribe(msg => {
                    try {
                        observer.OnNext(msg.Payload.Message.ToArray());
                    } catch (Exception ex) {
                        Log.Error(m => m("Error while publishing message to observer for topic {0}.", topic), ex);
                    }
                });

                // Unsubscribe from the topic on the server,
                return(Disposable.Create(() => {
                    Log.Info(m => m("Last subscriber gone for topic '{0}', unsubscribing on broker.", topic));

                    // stop processing publish messages for this topic received by thethe publishing manager.
                    msgPubSub.Dispose();

                    // build a unsubscribe message for the caller and send it off to the broker.
                    var unsubscribeMsg = new MqttUnsubscribeMessage().WithMessageIdentifier(
                        messageIdentifierDispenser.GetNextMessageIdentifier("unsubscriptions"))
                                         .WithMessageIdentifier(msgId)
                                         .FromTopic(topic);
                    connectionHandler.SendMessage(unsubscribeMsg);
                }));
            });

            // Publish and refcount so we can share the single subscription amongst all
            // subscribers and dispose automatically when everyone has disposed their
            // subscriptions.
            return(observable.Publish()
                   .RefCount());
        }