예제 #1
0
        private async Task Close(bool shallNotifyUserSide)
        {
            if (Interlocked.Exchange(ref _state, _closed) == _closed)
            {
                return;
            }

            Clean();

            if (shallNotifyUserSide)
            {
                Loger.DebugFormat("Disconnected from server [{0}] with dispatcher [{1}] on [{2}].",
                                  this.RemoteEndPoint,
                                  _dispatcher.GetType().Name,
                                  DateTime.UtcNow.ToString(@"yyyy-MM-dd HH:mm:ss.fffffff"));
                try
                {
                    await _dispatcher.OnServerDisconnected(this);
                }
                catch (Exception ex)
                {
                    HandleUserSideError(ex);
                }
            }
        }
예제 #2
0
        public async Task Connect()
        {
            int origin = Interlocked.CompareExchange(ref _state, _connecting, _none);

            if (origin == _disposed)
            {
                throw new ObjectDisposedException(GetType().FullName);
            }
            else if (origin != _none)
            {
                throw new InvalidOperationException("This tcp socket client has already connected to server.");
            }

            try
            {
                _tcpClient = _localEndPoint != null ? new TcpClient(_localEndPoint) : new TcpClient(_remoteEndPoint.Address.AddressFamily);

                var awaiter = _tcpClient.ConnectAsync(_remoteEndPoint.Address, _remoteEndPoint.Port);
                if (!awaiter.Wait(ConnectTimeout))
                {
                    await Close(false);

                    throw new TimeoutException(string.Format(
                                                   "Connect to [{0}] timeout [{1}].", _remoteEndPoint, ConnectTimeout));
                }

                ConfigureClient();
                var negotiator = NegotiateStream(_tcpClient.GetStream());
                if (!negotiator.Wait(ConnectTimeout))
                {
                    await Close(false);

                    throw new TimeoutException(string.Format(
                                                   "Negotiate SSL/TSL with remote [{0}] timeout [{1}].", _remoteEndPoint, ConnectTimeout));
                }
                _stream = negotiator.Result;

                _receiveBuffer       = _bufferManager.BorrowBuffer();
                _receiveBufferOffset = 0;

                if (Interlocked.CompareExchange(ref _state, _connected, _connecting) != _connecting)
                {
                    throw new ObjectDisposedException(GetType().FullName);
                }

                _log.DebugFormat("Connected to server [{0}] with dispatcher [{1}] on [{2}].",
                                 this.RemoteEndPoint,
                                 _dispatcher.GetType().Name,
                                 DateTime.UtcNow.ToString(@"yyyy-MM-dd HH:mm:ss.fffffff"));
                bool isErrorOccurredInUserSide = false;
                try
                {
                    await _dispatcher.OnServerConnected(this);
                }
                catch (Exception ex)
                {
                    isErrorOccurredInUserSide = true;
                    HandleUserSideError(ex);
                }

                if (!isErrorOccurredInUserSide)
                {
                    Task.Run(async() =>
                    {
                        await Process();
                    })
                    .Forget();
                }
                else
                {
                    await Close();
                }
            }
            catch (ObjectDisposedException) { }
            catch (Exception ex)
            {
                _log.Error(ex.Message, ex);
                throw;
            }
        }
예제 #3
0
        public async Task Connect()
        {
            int origin = Interlocked.Exchange(ref _state, _connecting);

            if (!(origin == _none || origin == _closed))
            {
                await Close(false);

                throw new InvalidOperationException("This tcp socket client is in invalid state when connecting.");
            }

            try
            {
                Clean();

                _tcpClient = _localEndPoint != null ?
                             new TcpClient(_localEndPoint) :
                             new TcpClient(_remoteEndPoint.Address.AddressFamily);
                SetSocketOptions();

                var awaiter = _tcpClient.ConnectAsync(_remoteEndPoint.Address, _remoteEndPoint.Port);
                if (!awaiter.Wait(ConnectTimeout))
                {
                    await Close(false);

                    throw new TimeoutException(string.Format(
                                                   "Connect to [{0}] timeout [{1}].", _remoteEndPoint, ConnectTimeout));
                }

                var negotiator = NegotiateStream(_tcpClient.GetStream());
                if (!negotiator.Wait(ConnectTimeout))
                {
                    await Close(false);

                    throw new TimeoutException(string.Format(
                                                   "Negotiate SSL/TSL with remote [{0}] timeout [{1}].", _remoteEndPoint, ConnectTimeout));
                }
                _stream = negotiator.Result;

                if (_receiveBuffer == default(ArraySegment <byte>))
                {
                    _receiveBuffer = _configuration.BufferManager.BorrowBuffer();
                }
                _receiveBufferOffset = 0;

                if (Interlocked.CompareExchange(ref _state, _connected, _connecting) != _connecting)
                {
                    await Close(false);

                    throw new InvalidOperationException("This tcp socket client is in invalid state when connected.");
                }

                _log.DebugFormat("Connected to server [{0}] with dispatcher [{1}] on [{2}].",
                                 this.RemoteEndPoint,
                                 _dispatcher.GetType().Name,
                                 DateTime.UtcNow.ToString(@"yyyy-MM-dd HH:mm:ss.fffffff"));
                bool isErrorOccurredInUserSide = false;
                try
                {
                    await _dispatcher.OnServerConnected(this);
                }
                catch (Exception ex)
                {
                    isErrorOccurredInUserSide = true;
                    HandleUserSideError(ex);
                }

                if (!isErrorOccurredInUserSide)
                {
                    Task.Factory.StartNew(async() =>
                    {
                        await Process();
                    },
                                          TaskCreationOptions.LongRunning)
                    .Forget();
                }
                else
                {
                    await Close();
                }
            }
            catch (Exception ex)
            {
                _log.Error(ex.Message, ex);
                throw;
            }
        }