Esempio n. 1
0
        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();
            }
        }
Esempio n. 2
0
        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();
            }
        }
Esempio n. 3
0
        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();
            }
        }
Esempio n. 4
0
        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();
            }
        }
Esempio n. 5
0
        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();
            }
        }
Esempio n. 6
0
        public override async ValueTask SendAsync(Action <PipeWriter> write)
        {
            try
            {
                await SendLock.WaitAsync();

                var writer = Out.Writer;
                write(writer);
                await writer.FlushAsync();
            }
            finally
            {
                SendLock.Release();
            }
        }
Esempio n. 7
0
        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();
            }
        }
Esempio n. 8
0
        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();
            }
        }
Esempio n. 9
0
        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();
            }
        }
Esempio n. 10
0
        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();
            }
        }
Esempio n. 11
0
        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();
            }
        }
Esempio n. 12
0
        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);
            }
        }