private async Task <DataLink> CreateDataLinkAsServerAsync(IPEndPoint remote, Stream stream) { var decoder = new DataLinkDecoder(); // 1024 is enough for current connect message. using (var owner = MemoryPool <byte> .Shared.Rent(1024)) { int count = 0; while (true) { count += await stream.ReadAsync(owner.Memory.Slice(count)); if (decoder.TryParseTransportMessage(new ReadOnlySequence <byte>(owner.Memory.Slice(0, count)), out var tm)) { if (tm.Type != DataLinkMessageType.Connect) { stream.Close(); return(null); } var connect = decoder.ParseConnect(tm.Content); var dlc = _dlcStore.Get(connect.ServiceName, connect.Args); if (dlc == null) { stream.Close(); return(null); } if (connect.ServiceName != dlc.ServiceName) { stream.Close(); return(null); } if (connect.InstanceName == dlc.Name) { stream.Close(); return(null); } using (var cm = DataLinkEncoder.Encode(new DCConnectMessage(dlc.ServiceName, dlc.Name, LocalPort, default))) { await stream.WriteAsync(cm.Memory); } var moreData = owner.Memory.Slice(tm.Length, count - tm.Length); return(dlc.CreateInternal(remote, stream, decoder, connect, moreData)); } } } }
private async Task ParseMessageAsync(PipeReader reader) { while (true) { try { var result = await reader.ReadAsync(); var buffer = result.Buffer; if (result.IsCanceled) { break; } while (!buffer.IsEmpty && _decoder.TryParseTransportMessage(buffer, out var message)) { buffer = buffer.Slice(message.Length); if (!ParseCore(message.Content, message.Type)) { break; } } // Tell the PipeReader how much of the buffer we have consumed reader.AdvanceTo(buffer.Start, buffer.End); // Stop reading if there's no more data coming if (result.IsCompleted) { break; } } catch (Exception ex) { _handler.OnError(this, ex); break; } } // Mark the PipeReader as complete reader.Complete(); _inPipe.Writer.Complete(); }