public async Task SubscribeToUserMessages(Func <User, Task> userMessageHandler) { await InternalClient.SubscribeAsync(_settings.UserMessagesTopic); UserMessageHandler = userMessageHandler; }
/// <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); } }