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 }
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); }
/// <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()); }
/// <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()); }