/// <summary>
        /// Diposes the underlying socket and other objects used by this instance.
        /// </summary>
        public override void Dispose()
        {
            IsDead = true;
            if (_disposed)
            {
                return;
            }

            _disposed = true;

            try
            {
                if (Socket != null)
                {
                    if (Socket.Connected)
                    {
                        Socket.Shutdown(SocketShutdown.Both);
                        Socket.Close(ConnectionPool.Configuration.ShutdownTimeout);
                    }
                    else
                    {
                        Socket.Close();
                        Socket.Dispose();
                    }
                }
                _allocator.ReleaseBuffer(_eventArgs);
                _eventArgs.Dispose();
                _requestCompleted.Dispose();
            }
            catch (Exception e)
            {
                Log.Info(e);
            }
        }
        private async Task <byte[]> SendAsync(byte[] buffer, CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();

            var opaque = Converter.ToUInt32(buffer, HeaderIndexFor.Opaque);
            var state  = new SocketAsyncState
            {
                Data          = MemoryStreamFactory.GetMemoryStream(),
                Opaque        = opaque,
                CorrelationId = CreateCorrelationId(opaque)
            };

            await _sslStream.WriteAsync(buffer, 0, buffer.Length, cancellationToken).ContinueOnAnyContext();

            try
            {
                state.SetIOBuffer(BufferAllocator.GetBuffer());

                while (state.BytesReceived < state.BodyLength + 24)
                {
                    cancellationToken.ThrowIfCancellationRequested();

                    var bytesReceived = await _sslStream.ReadAsync(state.Buffer, state.BufferOffset, state.BufferLength, cancellationToken).ContinueOnAnyContext();

                    state.BytesReceived += bytesReceived;

                    if (state.BytesReceived == 0)
                    {
                        // No more bytes were received, go ahead and exit the loop
                        break;
                    }
                    if (state.BodyLength == 0)
                    {
                        // Reading header, so get the BodyLength
                        state.BodyLength = Converter.ToInt32(state.Buffer, state.BufferOffset + HeaderIndexFor.Body);
                    }

                    state.Data.Write(state.Buffer, state.BufferOffset, bytesReceived);
                }
            }
            finally
            {
                if (state.IOBuffer != null)
                {
                    BufferAllocator.ReleaseBuffer(state.IOBuffer);
                }
            }

            return(state.Data.ToArray());
        }
        /// <summary>
        /// Disposes the underlying socket and other objects used by this instance.
        /// </summary>
        public override void Dispose()
        {
            Log.DebugFormat("Disposing {0}", _identity);
            if (Disposed || InUse && !IsDead)
            {
                return;
            }
            Disposed = true;
            IsDead   = true;

            try
            {
                if (Socket != null)
                {
                    if (Socket.Connected)
                    {
                        Socket.Shutdown(SocketShutdown.Both);
                        Socket.Close(ConnectionPool.Configuration.ShutdownTimeout);
                    }
                    else
                    {
                        Socket.Close();
                        Socket.Dispose();
                    }
                }
                //call the bases dispose to cleanup the timer
                base.Dispose();

                _eventArgs.Dispose();
                _requestCompleted.Dispose();
            }
            catch (Exception e)
            {
                Log.Info(e);
            }

            try
            {
                // Release the buffer in a separate try..catch block, because we want to ensure this happens
                // even if other steps fail.  Otherwise we will run out of buffers when the ConnectionPool reaches
                // its maximum size.

                BufferAllocator.ReleaseBuffer(_eventArgs);
            }
            catch (Exception e)
            {
                Log.Info(e);
            }
        }
Example #4
0
        /// <summary>
        /// Disposes the underlying socket and other objects used by this instance.
        /// </summary>
        public override void Dispose()
        {
            Log.DebugFormat("Disposing {0}", _identity);
            if (Disposed || InUse && !IsDead)
            {
                return;
            }
            Disposed = true;
            IsDead   = true;

            try
            {
                if (Socket != null)
                {
                    if (Socket.Connected)
                    {
                        Socket.Shutdown(SocketShutdown.Both);
                        Socket.Close(ConnectionPool.Configuration.ShutdownTimeout);
                    }
                    else
                    {
                        Socket.Close();
                        Socket.Dispose();
                    }
                }
                //call the bases dispose to cleanup the timer
                base.Dispose();

                _allocator.ReleaseBuffer(_eventArgs);
                _eventArgs.Dispose();
                _requestCompleted.Dispose();
            }
            catch (Exception e)
            {
                Log.Info(e);
            }
        }
        public override async void SendAsync(byte[] request, Func <SocketAsyncState, Task> callback)
        {
            ExceptionDispatchInfo capturedException = null;
            SocketAsyncState      state             = 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).ConfigureAwait(false);

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

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

                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).ConfigureAwait(false);

                    await state.Data.WriteAsync(state.Buffer, state.BufferOffset, state.BytesReceived - (int)state.Data.Length).ConfigureAwait(false);
                }
                await callback(state).ConfigureAwait(false);
            }
            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
                    }).ConfigureAwait(false);
                }
                else
                {
                    state.Exception = sourceException;
                    await state.Completed(state).ConfigureAwait(false);

                    Log.Debug(sourceException);
                }
            }
        }