Exemplo n.º 1
0
            async Task WriteOnceAsync()
            {
                await reset.WaitAsync();

                while (!token.IsCancellationRequested && queue.TryDequeue(out var packet))
                {
                    // quickly estimate the maximum required length for this message. our estimation is as follows:
                    //
                    //     - [payload]
                    //         - take the message length, and add the chunk + message headers.
                    //
                    //     - [chunk headers]
                    //         - all chunk headers begin with a 0-3 byte header, indicating chunk stream id + message header
                    //             format.
                    //         - the one byte variant can encode chunk stream ids up to and including #63. we don't expect to
                    //             encode that many streams right now (unless a user library wants it), so we can assume 1 byte
                    //             chunk headers for now.
                    //~
                    //     - [message headers]
                    //         - the first message header must be a type 0 (new) header, which is 11 bytes large.
                    //         - all further message headers can be a type 3 (continuation) header, which is 0 bytes large.
                    //
                    //     - [total]
                    //         - message_length + chunk_count * 1 + 11
                    //
                    var packetLength       = packet.Span.Length;
                    var chunkCount         = packetLength / chunkLength + 1;
                    var estimatedMaxLength = packetLength + chunkCount + 11;
                    var writer             = new AmfWriter(estimatedMaxLength, context);

                    var previous = streams.TryGetValue(packet.StreamId, out var value) ? value : default(ChunkStream.Snapshot);
                    var next     = previous.Clone();

                    next.Ready           = true;
                    next.ContentType     = packet.Type;
                    next.ChunkStreamId   = packet.StreamId;
                    next.MessageStreamId = 0;
                    next.MessageLength   = packetLength;
                    next.Timestamp       = Ts.CurrentTime;

                    streams[packet.StreamId] = next;
                    ChunkStream.WriteTo(writer, previous, next, chunkLength, packet.Span);

                    await stream.WriteAsync(writer.Span, token);

                    writer.Return();
                }
            }