private async Task WriteHandshakeAsync(CancellationToken cancellationToken) { if (HasSent) { return; } if (!await _writeLock.WaitAsync(_timeout, cancellationToken).ConfigureAwait(false)) { throw new TimeoutException("Sending handshake timed out."); } try { _lock.Write(() => _hasSent = true, (int)_timeout.TotalMilliseconds); foreach (var protocol in _protocols) { await MultistreamMuxer.DelimWriteAsync(_ms, Encoding.UTF8.GetBytes(protocol), cancellationToken).ConfigureAwait(false); } await _ms.FlushAsync(cancellationToken); } finally { _writeLock.Release(); } }
private async Task ReadHandshakeAsync(CancellationToken cancellationToken) { if (HasReceived) { return; } if (!await _readLock.WaitAsync(_timeout, cancellationToken).ConfigureAwait(false)) { throw new TimeoutException("Receiving handshake timed out."); } try { _lock.Write(() => _hasReceived = true, (int)_timeout.TotalMilliseconds); foreach (var protocol in _protocols) { var token = await MultistreamMuxer.ReadNextTokenAsync(_ms, cancellationToken).ConfigureAwait(false); if (token != protocol) { throw new Exception($"Protocol mismatch, {token} != {protocol}"); } } } finally { _readLock.Release(); } }