public async Task <string> SendAsync(string messageToSend) { await SendLock.WaitAsync(); try { CommunicationLog.RawMessageSending(messageToSend); await SendAsync(ClientWriter, messageToSend); CommunicationLog.RawMessageSent(messageToSend); do { if (MessageResponses.TryDequeue(out var result)) { return(result); } await Task.Delay(TimeSpan.FromMilliseconds(10)).ConfigureAwait(false); } while (Connected); return(null); } finally { SendLock.Release(); } }
private async Task <IConnection> SendPreambleAsync(IConnection connection, ArraySegment <byte> preamble, TimeSpan timeout) { var timeoutHelper = new TimeoutHelper(timeout); // initialize a new decoder _decoder = new ClientDuplexDecoder(0); byte[] ackBuffer = new byte[1]; if (!await SendLock.WaitAsync(TimeoutHelper.ToMilliseconds(timeout))) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new TimeoutException( SR.Format(SR.CloseTimedOut, timeout), TimeoutHelper.CreateEnterTimedOutException(timeout))); } try { await connection.WriteAsync(preamble.Array, preamble.Offset, preamble.Count, true, timeoutHelper.RemainingTime()); if (_upgrade != null) { StreamUpgradeInitiator upgradeInitiator = _upgrade.CreateUpgradeInitiator(this.RemoteAddress, this.Via); await upgradeInitiator.OpenAsync(timeoutHelper.RemainingTime()); var connectionWrapper = new OutWrapper <IConnection>(); connectionWrapper.Value = connection; bool upgradeInitiated = await ConnectionUpgradeHelper.InitiateUpgradeAsync(upgradeInitiator, connectionWrapper, _decoder, this, timeoutHelper.RemainingTime()); connection = connectionWrapper.Value; if (!upgradeInitiated) { await ConnectionUpgradeHelper.DecodeFramingFaultAsync(_decoder, connection, this.Via, MessageEncoder.ContentType, timeoutHelper.RemainingTime()); } SetRemoteSecurity(upgradeInitiator); await upgradeInitiator.CloseAsync(timeoutHelper.RemainingTime()); await connection.WriteAsync(ClientDuplexEncoder.PreambleEndBytes, 0, ClientDuplexEncoder.PreambleEndBytes.Length, true, timeoutHelper.RemainingTime()); } int ackBytesRead = await connection.ReadAsync(ackBuffer, 0, ackBuffer.Length, timeoutHelper.RemainingTime()); if (!ConnectionUpgradeHelper.ValidatePreambleResponse(ackBuffer, ackBytesRead, _decoder, Via)) { await ConnectionUpgradeHelper.DecodeFramingFaultAsync(_decoder, connection, Via, MessageEncoder.ContentType, timeoutHelper.RemainingTime()); } return(connection); } finally { SendLock.Release(); } }
protected async Task CloseOutputSessionAsync(TimeSpan timeout) { ThrowIfNotOpened(); ThrowIfFaulted(); TimeoutHelper timeoutHelper = new TimeoutHelper(timeout); // If timeout == TimeSpan.MaxValue, then we want to pass Timeout.Infinite as // SemaphoreSlim doesn't accept timeouts > Int32.MaxValue. // Using TimeoutHelper.RemainingTime() would yield a value less than TimeSpan.MaxValue // and would result in the value Int32.MaxValue so we must use the original timeout specified. if (!await SendLock.WaitAsync(TimeoutHelper.ToMilliseconds(timeout))) { if (WcfEventSource.Instance.CloseTimeoutIsEnabled()) { WcfEventSource.Instance.CloseTimeout(SR.Format(SR.CloseTimedOut, timeout)); } throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new TimeoutException( SR.Format(SR.CloseTimedOut, timeout), TimeoutHelper.CreateEnterTimedOutException(timeout))); } try { // check again in case the previous send faulted while we were waiting for the lock ThrowIfFaulted(); // we're synchronized by sendLock here if (_isOutputSessionClosed) { return; } _isOutputSessionClosed = true; bool shouldFault = true; try { await CloseOutputSessionCoreAsync(timeout); OnOutputSessionClosed(ref timeoutHelper); shouldFault = false; } finally { if (shouldFault) { Fault(); } } } finally { SendLock.Release(); } }
protected async Task CloseOutputSessionAsync(CancellationToken token) { ThrowIfNotOpened(); ThrowIfFaulted(); try { await SendLock.WaitAsync(token); } catch (OperationCanceledException) { // TODO: Fix the timeout value reported throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new TimeoutException( SR.Format(SR.CloseTimedOut, TimeSpan.Zero), TimeoutHelper.CreateEnterTimedOutException(TimeSpan.Zero))); } try { // check again in case the previous send faulted while we were waiting for the lock ThrowIfFaulted(); // we're synchronized by sendLock here if (_isOutputSessionClosed) { return; } _isOutputSessionClosed = true; bool shouldFault = true; try { await CloseOutputSessionCoreAsync(token); OnOutputSessionClosed(token); shouldFault = false; } finally { if (shouldFault) { Fault(); } } } finally { SendLock.Release(); } }
protected override void OnSend(Message message, TimeSpan timeout) { ThrowIfDisposedOrNotOpen(); TimeoutHelper timeoutHelper = new TimeoutHelper(timeout); // If timeout == TimeSpan.MaxValue, then we want to pass Timeout.Infinite as // SemaphoreSlim doesn't accept timeouts > Int32.MaxValue. // Using TimeoutHelper.RemainingTime() would yield a value less than TimeSpan.MaxValue // and would result in the value Int32.MaxValue so we must use the original timeout specified. if (!SendLock.Wait(TimeoutHelper.ToMilliseconds(timeout))) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new TimeoutException( SR.Format(SR.SendToViaTimedOut, Via, timeout), TimeoutHelper.CreateEnterTimedOutException(timeout))); } try { // check again in case the previous send faulted while we were waiting for the lock ThrowIfDisposedOrNotOpen(); ThrowIfOutputSessionClosed(); bool success = false; try { ApplyChannelBinding(message); OnSendCore(message, timeoutHelper.RemainingTime()); success = true; if (WcfEventSource.Instance.MessageSentByTransportIsEnabled()) { EventTraceActivity eventTraceActivity = EventTraceActivityHelper.TryExtractActivity(message); WcfEventSource.Instance.MessageSentByTransport(eventTraceActivity, RemoteAddress.Uri.AbsoluteUri); } } finally { if (!success) { Fault(); } } } finally { SendLock.Release(); } }
public override async ValueTask SendAsync(Action <PipeWriter> write) { try { await SendLock.WaitAsync(); var writer = Out.Writer; write(writer); await writer.FlushAsync(); } finally { SendLock.Release(); } }
public override async ValueTask SendAsync <TPackage>(IPackageEncoder <TPackage> packageEncoder, TPackage package) { try { await SendLock.WaitAsync(); var writer = Out.Writer; WritePackageWithEncoder <TPackage>(writer, packageEncoder, package); await writer.FlushAsync(); } finally { SendLock.Release(); } }
public override async ValueTask SendAsync(ReadOnlyMemory <byte> buffer) { try { await SendLock.WaitAsync(); var writer = Out.Writer; WriteBuffer(writer, buffer); await writer.FlushAsync(); } finally { SendLock.Release(); } }
private IConnection SendPreamble(IConnection connection, ArraySegment <byte> preamble, ref TimeoutHelper timeoutHelper) { TimeSpan timeout = timeoutHelper.RemainingTime(); if (!SendLock.Wait(TimeoutHelper.ToMilliseconds(timeout))) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new TimeoutException( SR.Format(SR.CloseTimedOut, timeout), TimeoutHelper.CreateEnterTimedOutException(timeout))); } try { // initialize a new decoder _decoder = new ClientDuplexDecoder(0); byte[] ackBuffer = new byte[1]; connection.Write(preamble.Array, preamble.Offset, preamble.Count, true, timeoutHelper.RemainingTime()); if (_upgrade != null) { StreamUpgradeInitiator upgradeInitiator = _upgrade.CreateUpgradeInitiator(this.RemoteAddress, this.Via); upgradeInitiator.Open(timeoutHelper.RemainingTime()); if (!ConnectionUpgradeHelper.InitiateUpgrade(upgradeInitiator, ref connection, _decoder, this, ref timeoutHelper)) { ConnectionUpgradeHelper.DecodeFramingFault(_decoder, connection, this.Via, MessageEncoder.ContentType, ref timeoutHelper); } SetRemoteSecurity(upgradeInitiator); upgradeInitiator.Close(timeoutHelper.RemainingTime()); connection.Write(ClientDuplexEncoder.PreambleEndBytes, 0, ClientDuplexEncoder.PreambleEndBytes.Length, true, timeoutHelper.RemainingTime()); } // read ACK int ackBytesRead = connection.Read(ackBuffer, 0, ackBuffer.Length, timeoutHelper.RemainingTime()); if (!ConnectionUpgradeHelper.ValidatePreambleResponse(ackBuffer, ackBytesRead, _decoder, Via)) { ConnectionUpgradeHelper.DecodeFramingFault(_decoder, connection, Via, MessageEncoder.ContentType, ref timeoutHelper); } return(connection); } finally { SendLock.Release(); } }
protected override async Task OnSendAsync(Message message, CancellationToken token) { ThrowIfDisposedOrNotOpen(); try { await SendLock.WaitAsync(token); } catch (OperationCanceledException) { // TODO: Fix the timeout value reported throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new TimeoutException( SR.Format(SR.SendToViaTimedOut, TimeSpan.Zero), TimeoutHelper.CreateEnterTimedOutException(TimeSpan.Zero))); } try { // check again in case the previous send faulted while we were waiting for the lock ThrowIfDisposedOrNotOpen(); ThrowIfOutputSessionClosed(); bool success = false; try { ApplyChannelBinding(message); await OnSendCoreAsync(message, token); success = true; } finally { if (!success) { Fault(); } } } finally { SendLock.Release(); } }
public override async ValueTask SendAsync <TPackage>(IPackageEncoder <TPackage> packageEncoder, TPackage package) { if (_enableSendingPipe) { await base.SendAsync(packageEncoder, package); return; } try { await SendLock.WaitAsync(); var writer = Out.Writer; WritePackageWithEncoder <TPackage>(writer, packageEncoder, package); await writer.FlushAsync(); await ProcessOutputRead(Out.Reader, null); } finally { SendLock.Release(); } }
protected override async Task OnSendAsync(Message message, TimeSpan timeout) { ThrowIfDisposedOrNotOpen(); TimeoutHelper timeoutHelper = new TimeoutHelper(timeout); // If timeout == TimeSpan.MaxValue, then we want to pass Timeout.Infinite as // SemaphoreSlim doesn't accept timeouts > Int32.MaxValue. // Using TimeoutHelper.RemainingTime() would yield a value less than TimeSpan.MaxValue // and would result in the value Int32.MaxValue so we must use the original timeout specified. if (!await SendLock.WaitAsync(TimeoutHelper.ToMilliseconds(timeout))) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new TimeoutException( SR.Format(SR.SendToViaTimedOut, Via, timeout), TimeoutHelper.CreateEnterTimedOutException(timeout))); } byte[] buffer = null; try { // check again in case the previous send faulted while we were waiting for the lock ThrowIfDisposedOrNotOpen(); ThrowIfOutputSessionClosed(); bool success = false; try { ApplyChannelBinding(message); var tcs = new TaskCompletionSource <bool>(this); AsyncCompletionResult completionResult; if (IsStreamedOutput) { completionResult = StartWritingStreamedMessage(message, timeoutHelper.RemainingTime(), s_onWriteComplete, tcs); } else { bool allowOutputBatching; ArraySegment <byte> messageData; allowOutputBatching = message.Properties.AllowOutputBatching; messageData = EncodeMessage(message); buffer = messageData.Array; completionResult = StartWritingBufferedMessage( message, messageData, allowOutputBatching, timeoutHelper.RemainingTime(), s_onWriteComplete, tcs); } if (completionResult == AsyncCompletionResult.Completed) { tcs.TrySetResult(true); } await tcs.Task; FinishWritingMessage(); success = true; if (WcfEventSource.Instance.MessageSentByTransportIsEnabled()) { EventTraceActivity eventTraceActivity = EventTraceActivityHelper.TryExtractActivity(message); WcfEventSource.Instance.MessageSentByTransport(eventTraceActivity, RemoteAddress.Uri.AbsoluteUri); } } finally { if (!success) { Fault(); } } } finally { SendLock.Release(); } if (buffer != null) { BufferManager.ReturnBuffer(buffer); } }