/// <summary> /// The ClientBase startup method. /// </summary> /// <returns></returns> public async Task <ClientBase> StartAsync() { if (string.IsNullOrEmpty(ServerIP) || ServerPort <= 0) { EventLogger.LogError("Cannot start as either server ip or port is invalid."); return(this); } if (IsConnected) { EventLogger.LogError("Client is already connected with the server."); return(this); } int connTries = 0; try { await ClientSemaphore.WaitAsync().ConfigureAwait(false); while (connTries < MAX_CONNECTION_RETRY_COUNT) { if (!Helpers.IsServerOnline(ServerIP)) { EventLogger.LogError($"Server is offline. RETRY_COUNT -> {connTries}"); connTries++; continue; } try { Connector = new TcpClient(ServerIP, ServerPort); } catch (SocketException) { connTries++; continue; } catch (Exception e) { EventLogger.LogException(e); break; } if (IsConnected) { break; } connTries++; } if (connTries >= MAX_CONNECTION_RETRY_COUNT && !IsConnected) { EventLogger.LogError($"Could not connect with server even after {connTries} retry count."); return(this); } if (!IsConnected) { EventLogger.LogError($"Could not connect with server. Server might be offline or unreachable!"); return(this); } EventLogger.LogInfo("Connected to server."); Connected?.Invoke(this, new OnConnectedEventArgs(DateTime.Now, ServerIP, ServerPort)); Helpers.InBackgroundThread(async() => { await ClientReceivingSemaphore.WaitAsync().ConfigureAwait(false); while (IsConnected) { try { NetworkStream stream = Connector.GetStream(); IsReceiving = true; if (!stream.DataAvailable) { await Task.Delay(1).ConfigureAwait(false); continue; } byte[] readBuffer = new byte[8000]; int dataCount = stream.Read(readBuffer, 0, readBuffer.Length); if (dataCount <= 0 || readBuffer.Length <= 0) { await Task.Delay(1).ConfigureAwait(false); continue; } string received = Encoding.ASCII.GetString(readBuffer); if (string.IsNullOrEmpty(received)) { await Task.Delay(1).ConfigureAwait(false); continue; } BaseResponse receivedObj = BaseResponse.DeserializeRequest <BaseResponse>(received); if (PreviousResponse != null && PreviousResponse.Equals(receivedObj)) { await Task.Delay(1).ConfigureAwait(false); continue; } ResponseReceived?.Invoke(this, new OnResponseReceivedEventArgs(DateTime.Now, receivedObj, received)); PreviousResponse = receivedObj; } catch (SocketException s) { EventLogger.LogTrace($"SOCKET EXCEPTION -> {s.SocketErrorCode.ToString()}"); break; } catch (Exception e) { EventLogger.LogError($"EXCEPTION -> {e.Message}"); continue; } } ClientReceivingSemaphore.Release(); EventLogger.LogInfo("Disconnected from server."); IsReceiving = false; Disconnected?.Invoke(this, new OnDisconnectedEventArgs(DateTime.Now, false, ServerIP, ServerPort, true)); }, "Client Receiving Thread", true); return(this); } finally { ClientSemaphore.Release(); } }
public async Task <(bool status, BaseResponse request)> SendWithResponseAsync(BaseRequest request, CancellationTokenSource token) { if (request == null || Connector == null) { return(false, null); } if (token == null) { token = new CancellationTokenSource(TimeSpan.FromSeconds(10)); } try { if (!await SendAsync(request).ConfigureAwait(false)) { return(false, null); } while (!token.Token.IsCancellationRequested) { if (!IsConnected || !Helpers.IsSocketConnected(Connector.Client)) { break; } if (Connector.Available <= 0) { await Task.Delay(1).ConfigureAwait(false); continue; } NetworkStream stream = Connector.GetStream(); if (!stream.DataAvailable) { await Task.Delay(1).ConfigureAwait(false); continue; } byte[] readBuffer = new byte[8000]; int dataCount = stream.Read(readBuffer, 0, readBuffer.Length); if (dataCount <= 0 || readBuffer.Length <= 0) { await Task.Delay(1).ConfigureAwait(false); continue; } string received = Encoding.ASCII.GetString(readBuffer); if (string.IsNullOrEmpty(received)) { await Task.Delay(1).ConfigureAwait(false); continue; } BaseResponse receivedObj = BaseResponse.DeserializeRequest <BaseResponse>(received); if (PreviousResponse != null && PreviousResponse.Equals(receivedObj)) { await Task.Delay(1).ConfigureAwait(false); continue; } PreviousResponse = receivedObj; return(true, receivedObj); } } finally { token.Dispose(); } return(false, null); }