/// <summary> /// Publishes the given packet to the broker. /// </summary> /// <param name="packet">Packet.</param> private ushort Publish(PublishPacket packet) { packet.Validate(); if (packet.QosLevel != MqttQos.AtMostOnce) { if (packet.PacketId == 0) { packet.PacketId = this.GetNextPacketId(); } // persistence needed only on qos levels 1 and 2 Persistence.RegisterOutgoingFlow(new OutgoingFlow() { PacketId = packet.PacketId, Retain = packet.Retain, Topic = packet.Topic, Qos = packet.QosLevel, Payload = packet.Message }); } try { IsPublishing = true; Send(packet); return(packet.PacketId); } catch { IsPublishing = false; throw; } }
// -- incoming publish events -- void OnPublishReceived(PublishPacket packet) { if (packet.QosLevel == MqttQos.ExactlyOnce) { OnQos2PublishReceived(packet); } else { if (PublishReceived != null) { PublishReceived(this, new PublishReceivedEventArgs(packet)); } if (packet.QosLevel == MqttQos.AtLeastOnce) { Send(new PubackPacket() { PacketId = packet.PacketId }); } } }
void OnQos2PublishReceived(PublishPacket packet) { if (!Persistence.IsIncomingFlowRegistered(packet.PacketId)) { if (PublishReceived != null) { PublishReceived(this, new PublishReceivedEventArgs(packet)); } // Register the incoming packetId, so duplicate messages can be filtered. // This is done after "ProcessIncomingPublish" because we can't assume the // mesage was received in the case that method throws an exception. Persistence.RegisterIncomingFlow(packet.PacketId); // the ideal would be to run `PubishReceived` and `Persistence.RegisterIncomingFlow` // in a single transaction (either both or neither succeeds). } Send(new PubrecPacket() { PacketId = packet.PacketId }); }
// sends a publish with dup flag in the case of a publish redelivery // or a pubrel in the case of qos2 message that we know was received by the broker private void Resume(OutgoingFlow flow) { if (flow.Qos == MqttQos.AtLeastOnce || (flow.Qos == MqttQos.ExactlyOnce && !flow.Received)) { var publish = new PublishPacket() { PacketId = flow.PacketId, QosLevel = flow.Qos, Topic = flow.Topic, Message = flow.Payload, DupFlag = true }; Publish(publish); } else if (flow.Qos == MqttQos.ExactlyOnce && flow.Received) { Pubrel(flow.PacketId); } Persistence.LastOutgoingPacketId = flow.PacketId; }
internal PublishReceivedEventArgs(PublishPacket packet) : base() { this.Packet = packet; }