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; }
Task AcceptMessageAsync(IChannelHandlerContext context, PublishPacket publish) { Message message; try { var buffer = new byte[publish.Payload.ReadableBytes]; publish.Payload.GetBytes(0, buffer); var bodyStream = new MemoryStream(buffer); bodyStream.Position = 0; message = new Message(bodyStream); Util.PopulateMessagePropertiesFromPacket(message, publish); } catch (Exception ex) { ShutdownOnError(context, ex); return(TaskConstants.Completed); } finally { publish.Release(); } this.onMessageReceived(message); return(TaskConstants.Completed); }
async Task PublishToServerAsync(IChannelHandlerContext context, IMessagingServiceClient sendingClient, PublishPacket packet, string messageType) { if (!this.ConnectedToService) { packet.Release(); return; } PreciseTimeSpan startedTimestamp = PreciseTimeSpan.FromStart; this.ResumeReadingIfNecessary(context); IMessage message = null; try { message = sendingClient.CreateMessage(packet.TopicName, packet.Payload); Util.CompleteMessageFromPacket(message, packet, this.settings); if (messageType != null) { message.Properties[this.settings.ServicePropertyPrefix + MessagePropertyNames.MessageType] = messageType; } await sendingClient.SendAsync(message); PerformanceCounters.MessagesSentPerSecond.Increment(); if (!this.IsInState(StateFlags.Closed)) { switch (packet.QualityOfService) { case QualityOfService.AtMostOnce: // no response necessary PerformanceCounters.InboundMessageProcessingTime.Register(startedTimestamp); break; case QualityOfService.AtLeastOnce: Util.WriteMessageAsync(context, PubAckPacket.InResponseTo(packet)) .OnFault(ShutdownOnWriteFaultAction, context); PerformanceCounters.InboundMessageProcessingTime.Register(startedTimestamp); // todo: assumes PUBACK is written out sync break; case QualityOfService.ExactlyOnce: ShutdownOnError(context, InboundPublishProcessingScope, new ProtocolGatewayException(ErrorCode.ExactlyOnceQosNotSupported, "QoS 2 is not supported.")); break; default: throw new ProtocolGatewayException(ErrorCode.UnknownQosType, "Unexpected QoS level: " + packet.QualityOfService.ToString()); } } message = null; } finally { message?.Dispose(); } }
private void publishCallback(PublishPacket packet) { bool invoked = false; foreach (var subscription in topicSubscriptions.Values) { if (subscription.IsMatch(packet.TopicName)) { packet.Payload.MarkReaderIndex(); subscription.Callback(packet); packet.Payload.ResetReaderIndex(); invoked = true; } } if (!invoked) { Logger.LogWarning($"Publish packet {packet} is not subscribed"); } packet.Release(); }