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); }
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(); } } }