protected async ValueTask ProcessOutgoingPacket(IOutputLogger?m, IOutgoingPacket outgoingPacket, CancellationToken cancellationToken)
 {
     if (cancellationToken.IsCancellationRequested)
     {
         return;
     }
     using (m?.SendingMessage(ref outgoingPacket, OutputPump.PConfig.ProtocolLevel))
     {
         if (outgoingPacket.Qos != QualityOfService.AtMostOnce)
         {
             // This must be done BEFORE writing the packet to avoid concurrency issues.
             _outgoingPacketStore.OnPacketSent(m, outgoingPacket.PacketId);
             // Explanation:
             // The receiver and input loop can run before the next line is executed.
         }
         await outgoingPacket.WriteAsync(OutputPump.PConfig.ProtocolLevel, _pipeWriter, cancellationToken);
     }
 }
예제 #2
0
        protected override async ValueTask <IOutgoingPacket> DoStorePacket(IActivityMonitor?m, IOutgoingPacket packet)
        {
            int packetSize = packet.GetSize(_protocolConfig.ProtocolLevel);

            m?.Trace($"Renting {packetSize} bytes to persist {packet}.");
            IMemoryOwner <byte> memOwner = MemoryPool <byte> .Shared.Rent(packetSize);

            PipeWriter pipe = PipeWriter.Create(memOwner.Memory.AsStream());   // And write their content to this memory.

            using (m?.OpenTrace($"Serializing {packet} into memory..."))
            {
                if (await packet.WriteAsync(_protocolConfig.ProtocolLevel, pipe, default) != WriteResult.Written)
                {
                    throw new InvalidOperationException("Didn't wrote packet correctly.");
                }
            }
            Memory <byte> slicedMem = memOwner.Memory.Slice(0, packetSize);

            base[packet.PacketId].Content.Storage = new StoredPacket(slicedMem, memOwner);
            return(new FromMemoryOutgoingPacket(slicedMem, packet.Qos, packet.PacketId));
        }