예제 #1
0
        public async Task <Stream> ConnectAsync(CancellationToken cancellation)
        {
            MultiplexSubstream substream;

            lock (Substreams)
            {
                substream          = new MultiplexSubstream(this, NextId);
                Substreams[NextId] = substream;
                ++NextId;
            }
            await SendAsync(linked => ProtobufEx.SerializeWithLengthPrefixAsync(Inner, new MultiplexPacket()
            {
                SubstreamId = OutboundSubstream = substream.Id
            }, PrefixStyle.Base128, linked), cancellation);

            return(substream);
        }
예제 #2
0
        async void ReceiveAsync()
        {
            try
            {
                while (true)
                {
                    var packet = await ProtobufEx.DeserializeWithLengthPrefixAsync <MultiplexPacket>(Inner, PrefixStyle.Base128, CancelAll.Token);

                    if (packet.SubstreamId != 0)
                    {
                        InboundSubstream = -packet.SubstreamId;
                    }
                    else if (InboundSubstream == 0)
                    {
                        throw new FormatException();
                    }
                    MultiplexSubstream substream;
                    bool created = false;
                    lock (Substreams)
                    {
                        if (!Substreams.TryGetValue(InboundSubstream, out substream) && InboundSubstream < 0)
                        {
                            Substreams[InboundSubstream] = substream = new MultiplexSubstream(this, InboundSubstream);
                            created = true;
                        }
                    }
                    if (created)
                    {
                        await Pending.AddAsync(substream, CancelAll.Token);
                    }
                    if (substream != null)
                    {
                        if (packet.Data != null && packet.Data.Length > 0)
                        {
                            await substream.ReceiveAsync(packet.Data, CancelAll.Token);
                        }
                        if (packet.EndOfStream)
                        {
                            await substream.ReceiveEndOfStream(CancelAll.Token);
                        }
                    }
                }
            }
            catch (EndOfStreamException)
            {
                Dispose();
                List <MultiplexSubstream> substreams;
                lock (Substreams)
                    substreams = Substreams.Values.ToList();
                foreach (var substream in substreams)
                {
                    substream.Dispose();
                }
            }
            catch (Exception e)
            {
                if (!CancelAll.Token.IsCancellationRequested)
                {
                    Logger.Error(e);
                    Dispose();
                }
            }
        }