private async Task PingProcess()
        {
            var pingPacket = _socketSerializer.CreatePingPacket();

            if (pingPacket != null)
            {
                while (!Disconnected)
                {
                    // Если никакого входящего
                    if ((DateTime.UtcNow - LastReadData).TotalSeconds > _socket.PingTimeOut)
                    {
                        await Send(pingPacket);

                        // Ожидаем то что Ping пакет уйдет и придет ответ
                        await Task.Delay(_socket.PacketDeliveryTimeOut * 1000);

                        var now     = DateTime.UtcNow;
                        var seconds = (now - LastReadData).TotalSeconds;
                        // Если за это время ответ на Ping не пришел, считаем что что связи нет и ее можно рвать
                        if (seconds > _socket.PingTimeOut)
                        {
                            _log.Add($"{_socket.SocketName}: Ping detected invalid connection:{Id}. Disconnect");
                            Disconnect();
                            break;
                        }
                    }
                    await Task.Delay(_socket.PingTimeOut);
                }
            }
        }
예제 #2
0
        private async Task ReadThread()
        {
            try
            {
                var stream = _socket.GetStream();

                while (!Disconnected)
                {
                    var tcpData = await _tcpSerializer.Deserialize(stream);

                    _socketStatistic.LastRecieveTime = DateTime.UtcNow;
                    _socketStatistic.Recieved       += tcpData.Item2;

                    if (tcpData.Item1 != null)
                    {
                        await TcpService.HandleDataFromSocket(tcpData.Item1);
                    }
                }
            }
            catch (Exception exception)
            {
                await Disconnect();

                _log.Add("Error ReadData [" + Id + "]:" + exception.Message);
            }
        }
예제 #3
0
 private async void SocketThread()
 {
     while (_working)
     {
         try
         {
             using (var connection = await Connect())
             {
                 var readTask = Task.Factory.StartNew(connection.StartReadData, TaskCreationOptions.LongRunning).Unwrap();
                 var pingTask = Task.Factory.StartNew(() => SocketPingProcess(connection), TaskCreationOptions.LongRunning).Unwrap();
                 await Task.WhenAny(readTask, pingTask);
             }
         }
         catch (SocketException se)
         {
             if (se.SocketErrorCode == SocketError.ConnectionRefused)
             {
                 _log?.Error(se, "Connection support exception");
                 _legacyLog?.Add("Connection support exception: " + se.Message);
             }
         }
         catch (Exception ex)
         {
             _log?.Error(ex, "Connection support fatal exception");
             _legacyLog?.Add("Connection support fatal exception:" + ex.Message);
         }
         finally
         {
             _service = default(TService);
             _log?.Warning("Connection timeout...");
             _legacyLog?.Add("Connection Timeout...");
             Thread.Sleep(_reconnectTimeOut);
         }
     }
 }
예제 #4
0
        public async Task Disconnect(Exception exc)
        {
            try
            {
                // Вычитаем состояние дисконнект в одном потоке и сменим состояние в Disconnect=true
                bool disconnected;


                lock (_disconnectLock)
                {
                    disconnected = Disconnected;
                    Disconnected = true;
                }

                // Если вычитанное состояние не было дисконнект- почистим все что необхдимо почистить
                if (!disconnected)
                {
                    // Если серверная служба следит за тем что сокет дисконнектнулся - сообщим об этом
                    DisconnectAction?.Invoke(this);

                    _socketStatistic.LastDisconnectionTime = DateTime.UtcNow;

                    _log?.Info("Disconnected", new { connectionId = Id });
                    _legacyLog?.Add("Disconnected[" + Id + "]");

                    if (_tcpService is ISocketNotifier socketNotifier)
                    {
                        await socketNotifier.Disconnect(exc);
                    }

                    (_tcpService as IDisposable)?.Dispose();
                }

                _socket.Dispose();
            }
            catch (Exception exception)
            {
                _log?.Error(exception, "Disconnection error", new { connectionId = Id });
                _legacyLog?.Add("Disconnect error. Id=" + Id + "; Msg:" + exception.Message);
            }
        }
예제 #5
0
        public void AcceptSocketThread()
        {
            _serverSocket = new TcpListener(_ipEndPoint);
            _serverSocket.Start();
            Log.Add("Started listening tcp socket: " + _ipEndPoint.Port);

            while (_thread != null)
            {
                try
                {
                    var acceptedSocket = _serverSocket.AcceptTcpClient();
                    var service        = _srvFactory();
                    var connection     = new TcpConnection(service, new TSerializer(), acceptedSocket, SocketStatistic, Log, _id++);
                    _connections.AddSocket(connection);
                    connection.StartReadData();
                }
                catch (Exception ex)
                {
                    Log.Add("Error accepting socket: " + ex.Message);
                }
            }
        }
예제 #6
0
 public void AddSocket(TcpConnection connection)
 {
     _lockSlim.EnterWriteLock();
     try
     {
         connection.DisconnectAction = RemoveSocket;
         _sockets.Add(connection.Id, connection);
     }
     finally
     {
         _lockSlim.ExitWriteLock();
     }
     _log.Add("Socket Accepted. Id=" + connection.Id.ToString(CultureInfo.InvariantCulture));
 }
        public async Task SocketThread()
        {
            while (_working)
            {
                try
                {
                    // Пытаемся создать соединение с сервером
                    var connection = await Connect();

                    _socketLog.Add($"Connected to server:{_ipEndPoint}. Id:{connection.Id}");
                    _serializer.Init();
                    // Запускаем процесс чтения данных. Он должен отвалиться сам когда потеряется связь
                    await connection.ReadThread();
                }

                catch (Exception ex)
                {
                    _socketLog.Add("Socket Thread Excepion: " + ex.Message);
                }

                await Task.Delay(_reconnectTimeOut);
            }
        }
예제 #8
0
        // Метод, который пытается сделать соединение с сервером
        private async Task <TcpConnection> Connect()
        {
            _log?.Add("Attempt To Connect:" + _ipEndPoint.Address + ":" + _ipEndPoint.Port);

            var tcpClient = new TcpClient();
            await tcpClient.ConnectAsync(_ipEndPoint.Address, _ipEndPoint.Port);

            _service = _srvFactory();
            SocketStatistic.Init();
            var connection = new TcpConnection(_service, new TTcpSerializer(), tcpClient, SocketStatistic, _log, _id++);

            _log?.Add("Connected. Id=" + connection.Id);

            return(connection);
        }
        public void HandleDataFromSocket(object data)
        {
            try
            {
                switch (data)
                {
                case TheResponseModel theResponse:
                    _log?.Info("Response", new { processId = theResponse.ProcessId, responseType = theResponse.GetType() });
                    _legacyLog?.Add($"Response ProcessId: {theResponse.ProcessId}");
                    _tasksManager.SetResult(theResponse.ProcessId, theResponse);
                    break;

                case TheNewResponseModel theNewResponse:
                    _log?.Info("Response", new { processId = theNewResponse.Id, responseType = theNewResponse.GetType() });
                    _legacyLog?.Add($"Response Id: {theNewResponse.Id}");
                    _newTasksManager.SetResult(theNewResponse.Id, theNewResponse);
                    break;

                case MarketOrderResponseModel theMarketOrderResponse:
                    _log?.Info("Response", new { processId = theMarketOrderResponse.Id, responseType = theMarketOrderResponse.GetType() });
                    _legacyLog?.Add($"Response Id: {theMarketOrderResponse.Id}");
                    _marketOrdersTasksManager.SetResult(theMarketOrderResponse.Id, theMarketOrderResponse);
                    break;

                case MeMultiLimitOrderResponseModel multiLimitOrderResponse:
                    _log?.Info("Response", new { processId = multiLimitOrderResponse.Id, responseType = multiLimitOrderResponse.GetType() });
                    _legacyLog?.Add($"Response Id: {multiLimitOrderResponse.Id}");
                    _multiOrdersTasksManager.SetResult(multiLimitOrderResponse.Id, multiLimitOrderResponse);
                    break;

                // No handlers for the following messages
                case MePingModel m0:
                case MeCashInOutModel m1:
                case MeLimitOrderModel m2:
                case MeMarketOrderObsoleteModel m3:
                case MeLimitOrderCancelModel m4:
                case MeUpdateBalanceModel m5:
                case MeNewTransferModel m6:
                case MeNewCashInOutModel m7:
                case MeNewSwapModel m8:
                case MeUpdateWalletCredsModel m9:
                case MeNewLimitOrderModel m10:
                case MeNewLimitOrderCancelModel m11:
                case MeNewMarketOrderModel m12:
                case MeMarketOrderModel m13:
                case MeNewUpdateBalanceModel m14:
                case MeMultiLimitOrderModel m15:
                case MeMultiLimitOrderCancelModel m16:
                case MeNewUpdateReservedBalanceModel m17:
                    break;

                default:
                    throw new ArgumentException(nameof(data), $"{data.GetType().Name} is not mapped. Please check the mapping in the MatchingEngineSerializer class");
                }
            }
            catch (KeyNotFoundException exception)
            {
                _log?.Error(exception, context: data);

                if (_ignoreErrors)
                {
                    _legacyLog?.Add($"Response: {data.ToJson()}");
                    _legacyLog?.Add(exception.ToString());
                }
                else
                {
                    throw;
                }
            }
        }