/// <summary> /// каждому типу клиента назначается свой порт и свой поставшик данных. /// </summary> public async Task RunServer(IExchangeDataProviderBase dataProvider) { if (dataProvider == null) { return; } OnPropertyChanged(nameof(IsConnect)); var token = Cts.Token; await Task.Run(async() => { TcpListener = TcpListener.Create(_ipPort); TcpListener.Start(); while (!token.IsCancellationRequested) { try { var tcpClient = await TcpListener.AcceptTcpClientAsync(); var task = ProcessClient(tcpClient, dataProvider, token); if (task.IsFaulted) { task.Wait(token); } } catch (ObjectDisposedException) //срабоатет при TcpListener.Stop() и если был вызван токен отмены то выйдем из цикла прослушки. { continue; } } }, token); }
private async Task ProcessClient(TcpClient c, IExchangeDataProviderBase dataProvider, CancellationToken token) { using (var client = new Client(c)) { _clients.Add(client); while (c.Connected && !token.IsCancellationRequested) { var connectionTask = client.ProcessAsync(dataProvider, token); lock (_lock) _hotTasks.Add(connectionTask); // обработка ошибок для клиентского потока try { await connectionTask; } catch (Exception) { // log } finally { lock (_lock) _hotTasks.Remove(connectionTask); } } _clients.Remove(client); } }
public async Task ProcessAsync(IExchangeDataProviderBase dataProvider, CancellationToken token) { //Ожидание получение информации из потока var actionBuffer = await ReadFromStreamAsync(dataProvider.CountSetDataByte, token); byte[] writeBuffer = null; if (dataProvider.IsSynchronized) { lock (dataProvider.SyncRoot) { if (dataProvider.SetDataByte(actionBuffer))//если полученные от клиента данные валидны, то отправим ему ответ { writeBuffer = dataProvider.GetDataByte(); } } } else { if (dataProvider.SetDataByte(actionBuffer))//если полученные от клиента данные валидны, то отправим ему ответ { writeBuffer = dataProvider.GetDataByte(); } } //Отправка ответа в поток if (writeBuffer != null) { await WriteInStreamAsync(writeBuffer, token); } }
/// <summary> /// Функция обмена по порту. Запрос-ожидание-ответ. /// Возвращает true если результат обмена успешен. /// </summary> public async Task <bool> DataExchangeAsync(int timeRespoune, IExchangeDataProviderBase dataProvider, CancellationToken ct) { if (!IsConnect) { return(false); } if (dataProvider == null) { return(false); } IsRunDataExchange = true; try { byte[] writeBuffer = dataProvider.GetDataByte(); if (writeBuffer != null && writeBuffer.Any()) { var readBuff = await RequestAndRespawnInstantlyAsync(writeBuffer, dataProvider.CountSetDataByte, timeRespoune, ct); dataProvider.SetDataByte(readBuff); } } catch (OperationCanceledException) { return(false); } catch (TimeoutException) { //ReOpen(); return(false); } IsRunDataExchange = false; return(true); }
public async Task ProcessAsync(IExchangeDataProviderBase dataProvider, CancellationToken token) { await Task.Run(async() => { var actionBuffer = await ReadFromStreamAsync(dataProvider.CountSetDataByte, token); if (dataProvider.SetDataByte(actionBuffer))//если полученные от клиента данные валидны, то отправим ему ответ { await WriteInStreamAsync(dataProvider.GetDataByte(), token); } }, token); }
public async Task RequestAndRespoune(IExchangeDataProviderBase dataProvider) { if (!IsConnect) { return; } if (dataProvider == null) { return; } IsRunDataExchange = true; if (await SendData(dataProvider)) { try { var data = await TakeData(dataProvider.CountSetDataByte, _timeRespoune, CancellationToken.None); dataProvider.SetDataByte(data); _countTryingTakeData = 0; } catch (OperationCanceledException) { StatusString = "операция прерванна"; if (++_countTryingTakeData > _numberTryingTakeData) { await ReConnect(); } } catch (TimeoutException) { StatusString = "Время на ожидание ответа вышло"; if (++_countTryingTakeData > _numberTryingTakeData) { await ReConnect(); } } catch (IOException) { await ReConnect(); } } else //не смогли отрпавить данные. СРАЗУ ЖЕ переподключение { await ReConnect(); } IsRunDataExchange = false; }
public async Task <bool> SendData(IExchangeDataProviderBase dataProvider) { byte[] buffer = dataProvider.GetDataByte(); try { if (_terminalClient != null && _terminalNetStream != null && _terminalClient.Client != null && _terminalClient.Client.Connected) { await _terminalNetStream.WriteAsync(buffer, 0, buffer.Length); return(true); } } catch (Exception ex) { StatusString = $"ИСКЛЮЧЕНИЕ SendDataToServer :{ex.Message}"; //LogException.WriteLog("Отправка данных серверу: ", ex, LogException.TypeLog.TcpIp); } return(false); }
private async Task ProcessClient(TcpClient c, IExchangeDataProviderBase dataProvider, CancellationToken token) { using (var client = new Client(c)) { // Если Ip нового клиента уже есть в списке, значит этот клиент выполнил аварийный реконект (без вызова Dispose), //Т.е. просто отключение терминала по питанию. //Вручную удалим старого клиента. var fatalDisposeClient = _clients.FirstOrDefault(cl => cl.Ip == client.Ip); if (fatalDisposeClient != null) { fatalDisposeClient.Dispose(); _clients.Remove(fatalDisposeClient); } _clients.Add(client); while (c.Connected && !token.IsCancellationRequested) { var exchangeTask = client.ProcessAsync(dataProvider, token); lock (_lock) _hotTasks.Add(exchangeTask); // обработка ошибок для клиентского потока try { await exchangeTask; } catch (Exception) { // log } finally { lock (_lock) _hotTasks.Remove(exchangeTask); } } _clients.Remove(client); } }