public void QosLevel2ExactlyOnce() { // expected response var expected = new[] { (byte)0x34, (byte)0x0E, (byte)0x0, (byte)0x4, (byte)'f', (byte)'r', (byte)'e', (byte)'d', (byte)0x0, (byte)0x0A, // message payload is here (byte)'h', (byte)'e', (byte)'l', (byte)'l', (byte)'o', (byte)'!', }; MqttMessage msg = new MqttPublishMessage() .WithQos(MqttQos.ExactlyOnce) .WithMessageIdentifier(10) .ToTopic("fred") .PublishData(new[] { (byte)'h', (byte)'e', (byte)'l', (byte)'l', (byte)'o', (byte)'!', } ); 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 + other bits Assert.Equal<byte>(expected[1], actual[1]); // remaining length Assert.Equal<byte>(expected[2], actual[2]); // first topic length byte Assert.Equal<byte>(expected[3], actual[3]); // second topic length byte Assert.Equal<byte>(expected[4], actual[4]); // f Assert.Equal<byte>(expected[5], actual[5]); // r Assert.Equal<byte>(expected[6], actual[6]); // e Assert.Equal<byte>(expected[7], actual[7]); // d Assert.Equal<byte>(expected[8], actual[8]); // h Assert.Equal<byte>(expected[9], actual[9]); // e Assert.Equal<byte>(expected[10], actual[10]); // l Assert.Equal<byte>(expected[11], actual[11]); // l Assert.Equal<byte>(expected[12], actual[12]); // o Assert.Equal<byte>(expected[13], actual[13]); // ! }
/// <summary> /// Raises the MessageReceived event. /// </summary> /// <param name="topic">The topic the message belongs to.</param> /// <param name="msg">The message received.</param> private void OnMessageReceived(PublicationTopic topic, MqttPublishMessage msg) { var handler = MessageReceived; if (handler != null) { handler(this, new PublishEventArgs(topic, msg)); } }
public void ClearPublishData() { // set up some publish data MqttPublishMessage msg = new MqttPublishMessage() .PublishData(new[] { (byte)0, (byte)1 }); Assert.Equal<int>(2, msg.Payload.Message.Count); msg.ClearPublishData(); Assert.Equal<int>(0, msg.Payload.Message.Count); }
/// <summary> /// Handles the processing of messages arriving from the message broker. /// </summary> /// <param name="mqttMessage"></param> private bool HandlePublishMessage(MqttMessage message) { MqttPublishMessage pubMsg = (MqttPublishMessage)message; Subscription subs = subscriptionsManager.GetSubscription(pubMsg.VariableHeader.TopicName); if (subs == null) { return(false); } // pass it on to the event subscribers. OnMessageAvailable(pubMsg.VariableHeader.TopicName, subs.DataProcessor.ConvertFromBytes(pubMsg.Payload.Message.ToArray())); return(true); }
/// <summary> /// Handles the receipt of publish messages from a message broker. /// </summary> /// <param name="msg">The message that was published.</param> /// <returns></returns> private bool HandlePublish(MqttMessage msg) { MqttPublishMessage pubMsg = (MqttPublishMessage)msg; bool publishSuccess = false; if (pubMsg.Header.Qos == MqttQos.AtMostOnce) { // QOS AtMostOnce 0 require no response. // send the message for processing to whoever is waiting. publishSuccess = publishMessageCallback(pubMsg); } else if (pubMsg.Header.Qos == MqttQos.AtLeastOnce) { // QOS AtLeastOnce 1 require an acknowledgement // send the message for processing to whoever is waiting. publishSuccess = publishMessageCallback(pubMsg); MqttPublishAckMessage ackMsg = new MqttPublishAckMessage() .WithMessageIdentifier(pubMsg.VariableHeader.MessageIdentifier); connectionHandler.SendMessage(ackMsg); } else if (pubMsg.Header.Qos == MqttQos.ExactlyOnce) { // QOS ExactlyOnce means we can't give it away yet, we gotta do a handshake // to make sure the broker knows we got it, and we know he knows we got it. // if we've already got it thats ok, it just means its being republished because // of a handshake breakdown, overwrite our existing one for the sake of it if (!receivedMessages.ContainsKey(pubMsg.VariableHeader.MessageIdentifier)) { receivedMessages[pubMsg.VariableHeader.MessageIdentifier] = pubMsg; } MqttPublishReceivedMessage pubRecv = new MqttPublishReceivedMessage() .WithMessageIdentifier(pubMsg.VariableHeader.MessageIdentifier); connectionHandler.SendMessage(pubRecv); publishSuccess = true; } return(publishSuccess); }
/// <summary> /// Publish a message to the broker on the specified topic. /// </summary> /// <param name="topic">The topic to send the message to.</param> /// <param name="qualityOfService">The QOS to use when publishing the message.</param> /// <param name="data">The message to send.</param> /// <returns>The message identifier assigned to the message.</returns> public short Publish<T, TPayloadConverter>(string topic, MqttQos qualityOfService, T data) where TPayloadConverter : IPayloadConverter<T>, new() { var msgId = messageIdentifierDispenser.GetNextMessageIdentifier(String.Format("Topic:{0}", topic)); Log.DebugFormat("Publishing message ID {0} on topic {1} using QOS {2}", msgId, topic, qualityOfService); var converter = GetPayloadConverter<TPayloadConverter>(); var msg = new MqttPublishMessage() .ToTopic(topic) .WithMessageIdentifier(msgId) .WithQos(qualityOfService) .PublishData(converter.ConvertToBytes(data)); // QOS level 1 or 2 messages need to be saved so we can do the ack processes if (qualityOfService == MqttQos.AtLeastOnce || qualityOfService == MqttQos.ExactlyOnce) { publishedMessages.Add(msgId, msg); } connectionHandler.SendMessage(msg); return msgId; }
/// <summary> /// Publish a message to the broker on the specified topic. /// </summary> /// <param name="topic">The topic to send the message to.</param> /// <param name="payload">The message to send.</param> /// <returns>The message identifier assigned to the message.</returns> public short Publish <TDataConverter>(string topic, MqttQos qualityOfService, object data) where TDataConverter : IPublishDataConverter { short msgID = MessageIdentifierDispenser.GetNextMessageIdentifier(String.Format("Topic:{0}", topic)); IPublishDataConverter converter = GetPublishDataConverter <TDataConverter>(); MqttPublishMessage msg = new MqttPublishMessage() .ToTopic(topic) .WithMessageIdentifier(msgID) .WithQos(qualityOfService) .PublishData(converter.ConvertToBytes(data)); // QOS level 1 or 2 messages need to be saved so we can do the ack processes if (qualityOfService == MqttQos.AtLeastOnce || qualityOfService == MqttQos.ExactlyOnce) { publishedMessages.Add(msgID, msg); } connectionHandler.SendMessage(msg); return(msgID); }
/// <summary> /// Creates a new instance of a PublishEventArgs class. /// </summary> /// <param name="publishMessage">The MQTT Publish Message that's been published.</param> public PublishEventArgs(MqttPublishMessage publishMessage) { PublishMessage = publishMessage; }
public void WithNonDefaultQos() { // set up some publish data MqttPublishMessage msg = new MqttPublishMessage() .ToTopic("mark") .WithQos(MqttQos.AtLeastOnce) .WithMessageIdentifier(4) .PublishData(new[] { (byte)9 }); var msgBytes = MessageSerializationHelper.GetMessageBytes(msg); // 2 (header + 6 (topic) + 2 (msg id) + 1 (data size) Assert.Equal<int>(11, msgBytes.Length); }
/// <summary> /// Creates a new instance of a PublishEventArgs class. /// </summary> /// <param name="topic">The parsed topic.</param> /// <param name="publishMessage">The MQTT Publish Message that's been published.</param> public PublishEventArgs(PublicationTopic topic, MqttPublishMessage publishMessage) { Topic = topic; PublishMessage = publishMessage; }
/// <summary> /// Raises the MessageReceived event. /// </summary> /// <param name="msg">The message received.</param> private void OnMessageReceived(MqttPublishMessage msg) { var handler = MessageReceived; if (handler != null) { handler(this, new PublishEventArgs(msg)); } }