public void OnPublish(IChannelHandlerContext context, PublishPacket packet) { switch (packet.QualityOfService) { case QualityOfService.AtMostOnce: publishCallback(packet); break; case QualityOfService.AtLeastOnce: publishCallback(packet); if (packet.PacketId != -1) { context.WriteAndFlushAsync(PubAckPacket.InResponseTo(packet)); } break; case QualityOfService.ExactlyOnce: if (packet.PacketId != -1) { var pubRecPacket = PubRecPacket.InResponseTo(packet); PendingQoS2Publish pendingQoS2Publish = new PendingQoS2Publish(packet, pubRecPacket); pendingIncomingQoS2Publishes.TryAdd(pubRecPacket.PacketId, pendingQoS2Publish); packet.Retain(); pendingQoS2Publish.Retransmit(eventLoopGroup.GetNext(), sendAndFlushAsync); context.WriteAndFlushAsync(pubRecPacket); } break; } }
public async Task PublishAsync(string topic, byte[] payload, QualityOfService qos = QualityOfService.AtMostOnce, bool retain = false) { TaskCompletionSource <object> future = new TaskCompletionSource <object>(); PublishPacket packet = new PublishPacket(qos, false, retain); packet.TopicName = topic; packet.PacketId = PacketIdProvider.NewPacketId(); packet.Payload = Unpooled.WrappedBuffer(payload); packet.Retain(); WriteResult result = await sendAndFlushAsync(packet); if (!result.Success) { packet.Release();//needed? future.SetException(result.Exception); } else if (qos == QualityOfService.AtLeastOnce) { packet.Release(); //needed? future.SetResult(null); //We don't get an ACK for QOS 0 } else { PendingPublish pendingPublish = new PendingPublish(packet, future);//return after PubAct(QoS=1)/PubRel(QoS=2) received. pendingPublishes.TryAdd(packet.PacketId, pendingPublish); pendingPublish.RetransmitPublish(eventLoopGroup.GetNext(), sendAndFlushAsync); } await future.Task; }
private PublishPacket duplicateRetainPublishPacket(PublishPacket packet) { var qos = packet.QualityOfService; var retain = packet.RetainRequested; PublishPacket result = new PublishPacket(qos, true, retain) { PacketId = packet.PacketId, Payload = packet.Payload, TopicName = packet.TopicName, }; result.Retain(); return(packet); }