Example #1
0
        /// <summary>
        /// Recieves an asynchronous recieve operation and loops until the response body has been read.
        /// </summary>
        /// <param name="socket">The <see cref="Socket"/> which the asynchronous operation is associated with.</param>
        /// <param name="e">The <see cref="SocketAsyncEventArgs"/> that is being used for the operation.</param>
        public void Receive(Socket socket, SocketAsyncEventArgs e)
        {
            while (true)
            {
                var state = (SocketAsyncState)e.UserToken;
                Log.Debug("Receive {0} bytes for opaque{1} with {2} on server {3} offset{4}", e.BytesTransferred, state.Opaque, Identity, EndPoint, state.SendOffset);
                if (e.SocketError == SocketError.Success)
                {
                    //socket was closed on recieving side
                    if (e.BytesTransferred == 0)
                    {
                        Log.Debug("Connection {0} has failed in receive with {1} bytes.", Identity, e.BytesTransferred);
                        IsDead = true;
                        if (state.Completed == null)
                        {
                            if (!Disposed)
                            {
                                _requestCompleted.Set();
                            }
                        }
                        else
                        {
                            ConnectionPool.Release(this);
                            state.Exception = new SocketException(10054);
                            state.Completed(state);
                        }
                        break;
                    }
                    state.BytesReceived += e.BytesTransferred;
                    state.Data.Write(e.Buffer, state.SendOffset, e.BytesTransferred);

                    //if first loop get the length of the body from the header
                    if (state.BodyLength == 0)
                    {
                        state.BodyLength = Converter.ToInt32(state.Data.ToArray(), HeaderIndexFor.Body);
                    }
                    if (state.BytesReceived < state.BodyLength + 24)
                    {
                        var bufferSize = state.BodyLength < Configuration.BufferSize
                            ? state.BodyLength
                            : Configuration.BufferSize;

                        e.SetBuffer(state.SendOffset, bufferSize);
                        var willRaiseCompletedEvent = socket.ReceiveAsync(e);
                        if (!willRaiseCompletedEvent)
                        {
                            continue;
                        }
                    }
                    else
                    {
                        //if the callback is null we are in blocking mode
                        if (state.Completed == null)
                        {
                            Log.Debug("Complete with set {0} with {1} on server {2}", state.Opaque, Identity, EndPoint);
                            _requestCompleted.Set();
                        }
                        else
                        {
                            Log.Debug("Complete {0} with {1} on server {2}", state.Opaque, Identity, EndPoint);
                            ConnectionPool.Release(this);
                            state.Completed(state);
                        }
                    }
                }
                else
                {
                    IsDead          = true;
                    state.Exception = new SocketException((int)e.SocketError);
                    Log.Debug("Error: {0} - {1}", Identity, state.Exception);
                    //if the callback is null we are in blocking mode
                    if (state.Completed == null)
                    {
                        if (!Disposed)
                        {
                            _requestCompleted.Set();
                        }
                    }
                    else
                    {
                        ConnectionPool.Release(this);
                        state.Completed(state);
                    }
                }
                break;
            }

            UpdateLastActivity();
        }
        public override async void SendAsync(byte[] request, Func <SocketAsyncState, Task> callback, ISpan span, ErrorMap errorMap)
        {
            ExceptionDispatchInfo capturedException = null;
            SocketAsyncState      state             = null;

            try
            {
                var opaque = Converter.ToUInt32(request, HeaderIndexFor.Opaque);
                state = new SocketAsyncState
                {
                    Data          = MemoryStreamFactory.GetMemoryStream(),
                    Opaque        = opaque,
                    Buffer        = request,
                    Completed     = callback,
                    DispatchSpan  = span,
                    CorrelationId = CreateCorrelationId(opaque),
                    ErrorMap      = errorMap
                };

                await _sslStream.WriteAsync(request, 0, request.Length).ContinueOnAnyContext();

                state.SetIOBuffer(BufferAllocator.GetBuffer());
                state.BytesReceived = await _sslStream.ReadAsync(state.Buffer, state.BufferOffset, state.BufferLength).ContinueOnAnyContext();

                //write the received buffer to the state obj
                await state.Data.WriteAsync(state.Buffer, state.BufferOffset, state.BytesReceived).ContinueOnAnyContext();

                state.BodyLength = Converter.ToInt32(state.Buffer, state.BufferOffset + HeaderIndexFor.BodyLength);
                while (state.BytesReceived < state.BodyLength + 24)
                {
                    var bufferLength = state.BufferLength - state.BytesSent < state.BufferLength
                        ? state.BufferLength - state.BytesSent
                        : state.BufferLength;

                    state.BytesReceived += await _sslStream.ReadAsync(state.Buffer, state.BufferOffset, bufferLength).ContinueOnAnyContext();

                    await state.Data.WriteAsync(state.Buffer, state.BufferOffset, state.BytesReceived - (int)state.Data.Length).ContinueOnAnyContext();
                }
                await callback(state).ContinueOnAnyContext();
            }
            catch (Exception e)
            {
                IsDead            = true;
                capturedException = ExceptionDispatchInfo.Capture(e);
            }
            finally
            {
                ConnectionPool.Release(this);
                if (state.IOBuffer != null)
                {
                    BufferAllocator.ReleaseBuffer(state.IOBuffer);
                }
            }

            if (capturedException != null)
            {
                var sourceException = capturedException.SourceException;
                if (state == null)
                {
                    await callback(new SocketAsyncState
                    {
                        Exception = capturedException.SourceException,
                        Status    = (sourceException is SocketException)
                            ? ResponseStatus.TransportFailure
                            : ResponseStatus.ClientFailure
                    }).ContinueOnAnyContext();
                }
                else
                {
                    state.Exception = sourceException;
                    await state.Completed(state).ContinueOnAnyContext();

                    Log.Debug(sourceException);
                }
            }
        }
        public override async void SendAsync(byte[] request, Func <SocketAsyncState, Task> callback)
        {
            SocketAsyncState state = null;

            byte[] buffer = null;
            try
            {
                state = new SocketAsyncState
                {
                    Data      = new MemoryStream(),
                    Opaque    = Converter.ToUInt32(request, HeaderIndexFor.Opaque),
                    Buffer    = request,
                    Completed = callback
                };

                await _sslStream.WriteAsync(request, 0, request.Length);

                state.Buffer        = BufferManager.TakeBuffer(Configuration.BufferSize);
                state.BytesReceived = await _sslStream.ReadAsync(state.Buffer, 0, Configuration.BufferSize);

                //write the received buffer to the state obj
                await state.Data.WriteAsync(state.Buffer, 0, state.BytesReceived);

                state.BodyLength = Converter.ToInt32(state.Buffer, HeaderIndexFor.BodyLength);
                while (state.BytesReceived < state.BodyLength + 24)
                {
                    var bufferLength = state.Buffer.Length - state.BytesSent < Configuration.BufferSize
                        ? state.Buffer.Length - state.BytesSent
                        : Configuration.BufferSize;

                    state.BytesReceived += await _sslStream.ReadAsync(state.Buffer, 0, bufferLength);

                    await state.Data.WriteAsync(state.Buffer, 0, state.BytesReceived - (int)state.Data.Length);
                }
                await callback(state);
            }
            catch (Exception e)
            {
                IsDead = true;
                if (state == null)
                {
                    callback(new SocketAsyncState
                    {
                        Exception = e,
                        Status    = (e is SocketException)
                            ? ResponseStatus.TransportFailure
                            : ResponseStatus.ClientFailure
                    });
                }
                else
                {
                    state.Exception = e;
                    state.Completed(state);
                    Log.Debug(e);
                }
            }
            finally
            {
                ConnectionPool.Release(this);
                if (buffer != null)
                {
                    BufferManager.ReturnBuffer(buffer);
                }
            }
        }
Example #4
0
 internal SslConnection(ConnectionPool <SslConnection> connectionPool, Socket socket, IByteConverter converter)
     : this(connectionPool, socket, new SslStream(new NetworkStream(socket)), converter)
 {
 }
 internal SslConnection(ConnectionPool <SslConnection> connectionPool, Socket socket, IByteConverter converter)
     : this(connectionPool, socket, new SslStream(new NetworkStream(socket), true, ServerCertificateValidationCallback), converter)
 {
 }
        /// <summary>
        /// Recieves an asynchronous recieve operation and loops until the response body has been read.
        /// </summary>
        /// <param name="socket">The <see cref="Socket"/> which the asynchronous operation is associated with.</param>
        /// <param name="e">The <see cref="SocketAsyncEventArgs"/> that is being used for the operation.</param>
        public void Receive(Socket socket, SocketAsyncEventArgs e)
        {
            while (true)
            {
                var state = (SocketAsyncState)e.UserToken;
                if (e.SocketError == SocketError.Success)
                {
                    //socket was closed on recieving side
                    if (e.BytesTransferred == 0)
                    {
                        _requestCompleted.Set();
                        return;
                    }
                    state.BytesReceived += e.BytesTransferred;
                    state.Data.Write(e.Buffer, 0, e.BytesTransferred);

                    //if first loop get the length of the body from the header
                    if (state.BodyLength == 0)
                    {
                        state.BodyLength = Converter.ToInt32(state.Data.GetBuffer(), HeaderIndexFor.Body);
                    }
                    if (state.BytesReceived < state.BodyLength + 24)
                    {
                        var bufferSize = state.BodyLength < Configuration.BufferSize
                            ? state.BodyLength
                            : Configuration.BufferSize;

                        e.SetBuffer(0, bufferSize);
                        var willRaiseCompletedEvent = socket.ReceiveAsync(e);
                        if (!willRaiseCompletedEvent)
                        {
                            continue;
                        }
                    }
                    else
                    {
                        //if the callback is null we are in blocking mode
                        if (state.Completed == null)
                        {
                            _requestCompleted.Set();
                        }
                        else
                        {
                            ConnectionPool.Release(this);
                            state.Completed(state);
                        }
                    }
                }
                else
                {
                    IsDead          = true;
                    state.Exception = new SocketException((int)e.SocketError);

                    //if the callback is null we are in blocking mode
                    if (state.Completed == null)
                    {
                        _requestCompleted.Set();
                    }
                    else
                    {
                        ConnectionPool.Release(this);
                        state.Completed(state);
                    }
                }
                break;
            }
        }