public async Task SubscribeToUserMessages(Func <User, Task> userMessageHandler)
        {
            await InternalClient.SubscribeAsync(_settings.UserMessagesTopic);

            UserMessageHandler = userMessageHandler;
        }
Beispiel #2
0
        /// <inheritdoc/>
        /// <exception cref="ArgumentException"></exception>
        public IObservable <MqttApplicationMessageReceivedEventArgs> Connect(string topic)
        {
            if (string.IsNullOrWhiteSpace(topic))
            {
                throw new ArgumentException($"'{nameof(topic)}' cannot be null or whitespace", nameof(topic));
            }

            ThrowIfDisposed();
            lock (topicSubscriptionCache)
            {
                // try get exiting observable for topic
                if (!topicSubscriptionCache.TryGetValue(topic, out IObservable <MqttApplicationMessageReceivedEventArgs> observable))
                {
                    // create new observable for topic
                    observable = Observable
                                 .Create <MqttApplicationMessageReceivedEventArgs>(async observer =>
                    {
                        // subscribe to topic
                        try
                        {
                            await InternalClient.SubscribeAsync(topic).ConfigureAwait(false);
                        }
                        catch (Exception exception)
                        {
                            logger.Error(exception, "Error while maintaining subscribe from topic.");
                            observer.OnError(exception);
                            return(Disposable.Empty);
                        }

                        // filter all received messages
                        // and subscribe to messages for this topic
                        var messageSubscription = applicationMessageReceived
                                                  .FilterTopic(topic)
                                                  .Subscribe(observer);

                        return(Disposable.Create(async() =>
                        {
                            // clean up subscription when no observer subscribed
                            lock (topicSubscriptionCache)
                            {
                                messageSubscription.Dispose();
                                topicSubscriptionCache.Remove(topic);
                            }
                            try
                            {
                                await InternalClient.UnsubscribeAsync(topic).ConfigureAwait(false);
                            }
                            catch (ObjectDisposedException) { }         // if disposed there is nothing to unsubscribe
                            catch (Exception exception)
                            {
                                logger.Error(exception, "Error while maintaining unsubscribe from topic.");
                            }
                        }));
                    })
                                 .Publish()   // publish from on source observable
                                 .RefCount(); // count subscriptions and dispose source observable when no subscription

                    // save observable for topic
                    lock (topicSubscriptionCache)
                        topicSubscriptionCache.Add(topic, observable);
                }
                return(observable);
            }
        }