Пример #1
0
        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;
        }
Пример #2
0
        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();
            }
        }
Пример #4
0
        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();
        }