Example #1
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 #2
0
 public void MultiWildcardOnlyTopicMatchesTopicStartingWithSeparator() {
     var topic = new SubscriptionTopic("#");
     Assert.True(topic.Matches(new PublicationTopic("/finance/ibm/closingprice")));
 }
Example #3
0
 public void MultiWildcardOnlyTopicMatchesAnyRandomTopic() {
     var topic = new SubscriptionTopic("#");
     Assert.True(topic.Matches(new PublicationTopic("finance/ibm/closingprice")));
 }
Example #4
0
 public void SingleLevelEqualTopicsMatch() {
     var topic = new SubscriptionTopic("finance");
     Assert.True(topic.Matches(new PublicationTopic("finance")));
 }
Example #5
0
 public void TopicsDifferingOnlyByCaseDoNotMatch() {
     var topic = new SubscriptionTopic("finance");
     Assert.False(topic.Matches(new PublicationTopic("Finance")));
 }       
Example #6
0
 public void TopicWithMultiWildcardDoesNotMatchTopicWithDifferenceBeforeWildcardLevel() {
     var topic = new SubscriptionTopic("finance/#");
     Assert.False(topic.Matches(new PublicationTopic("money/ibm")));
 }  
Example #7
0
 public void MultiLevelNonEqualTopicsDoNotMatch() {
     var topic = new SubscriptionTopic("finance/ibm/closingprice");
     Assert.False(topic.Matches(new PublicationTopic("some/random/topic")));
 }
Example #8
0
 public void TopicWithSingleWildcardAtEndMatchesAnythingInSameLevel() {
     var topic = new SubscriptionTopic("finance/+/closingprice");
     Assert.True(topic.Matches(new PublicationTopic("finance/ibm/closingprice")));
 }
Example #9
0
 public void TopicWithSingleWildcardAtEndDoesNotMatchTopicThatGoesDeeper() {
     var topic = new SubscriptionTopic("finance/+");
     Assert.False(topic.Matches(new PublicationTopic("finance/ibm/closingprice")));
 }
Example #10
0
 public void SingleLevelNonEqualTopicsDoNotMatch() {
     var topic = new SubscriptionTopic("finance");
     Assert.False(topic.Matches(new PublicationTopic("money")));
 }
Example #11
0
 public void TopicWithSingleWildcardAtEndMatchesTopicWithEmptyLastFragmentAtThatSpot() {
     var topic = new SubscriptionTopic("finance/ibm/+");
     Assert.True(topic.Matches(new PublicationTopic("finance/ibm/")));
 }
Example #12
0
 public void TopicWithSingleWildcardMatchesTopicEmptyFragmentAtThatPoint() {
     var topic = new SubscriptionTopic("finance/+/closingprice");
     Assert.True(topic.Matches(new PublicationTopic("finance//closingprice")));
 }
Example #13
0
 public void TopicWithSingleAndMultiWildcardMatchesTopicWithAnyValueAtThoseLevelsAndDeeper() {
     var topic = new SubscriptionTopic("finance/+/closingprice/month/#");
     Assert.True(topic.Matches(new PublicationTopic("finance/ibm/closingprice/month/october/2014")));
 }
Example #14
0
 public void TopicWithMoreThanOneSingleWildcardAtDifferentLevelsMatchesTopicWithAnyValueAtThoseLevels() {
     var topic = new SubscriptionTopic("finance/+/closingprice/month/+");
     Assert.True(topic.Matches(new PublicationTopic("finance/ibm/closingprice/month/october")));
 }
Example #15
0
 public void TopicWithMultiWildcardAtEndMatchesTopicThatDoesNotMatchSameDepth() {
     var topic = new SubscriptionTopic("finance/#");
     Assert.True(topic.Matches(new PublicationTopic("finance")));
 }
Example #16
0
 public void TopicWithSingleWildcardAtEndDoesNotMatchTopicThatDoesNotContainAnythingAtSameLevel() {
     var topic = new SubscriptionTopic("finance/+");
     Assert.False(topic.Matches(new PublicationTopic("finance")));
 }        
Example #17
0
 public void TopicWithMultiWildcardAtEndMatchesTopicWithAnythingAtWildcardLevel() {
     var topic = new SubscriptionTopic("finance/#");
     Assert.True(topic.Matches(new PublicationTopic("finance/ibm")));
 }