예제 #1
0
        public static async Task<PublishPacket> ComposePublishPacketAsync(IChannelHandlerContext context, Message message, QualityOfService qos, string topicName)
        {
            var packet = new PublishPacket(qos, false, false);
            packet.TopicName = PopulateMessagePropertiesFromMessage(topicName, message);
            if (qos > QualityOfService.AtMostOnce)
            {
                int packetId = GetNextPacketId();
                switch (qos)
                {
                    case QualityOfService.AtLeastOnce:
                        packetId &= 0x7FFF; // clear 15th bit
                        break;
                    case QualityOfService.ExactlyOnce:
                        packetId |= 0x8000; // set 15th bit
                        break;
                    default:
                        throw new ArgumentOutOfRangeException(nameof(qos), qos, null);
                }
                packet.PacketId = packetId;
            }
            using (Stream payloadStream = message.GetBodyStream())
            {
                long streamLength = payloadStream.Length;
                if (streamLength > MaxPayloadSize)
                {
                    throw new InvalidOperationException($"Message size ({streamLength} bytes) is too big to process. Maximum allowed payload size is {MaxPayloadSize}");
                }

                int length = (int)streamLength;
                IByteBuffer buffer = context.Channel.Allocator.Buffer(length, length);
                await buffer.WriteBytesAsync(payloadStream, length);
                Contract.Assert(buffer.ReadableBytes == length);

                packet.Payload = buffer;
            }
            return packet;
        }