/// <summary> /// Connect to server /// </summary> public async Task <bool> ConnectAsync() { Interlocked.Exchange(ref _connecting, new object()); // create new client var socket = new TcpClientSocket(_createDataProcessorFunc, _clientConfig, _loggerFactory); socket.ClientDisconnectedAction = new Action <ClientInfo>((info) => { Interlocked.Exchange(ref _socketClient, null)?.Disconnect(); if (_eventHandler != null) { _eventHandler.HandleClientDisconnected(info); } }); // replace with previous client Interlocked.Exchange(ref _socketClient, socket)?.Disconnect(); // reset utils _dataSynchronizator.Reset(); _dataProcessor.Reset(); _allowAutoReconnect = true; // add support for rpc and auto response socket.MsgReceivedAction = new Action <DataContainer>((msg) => { var id = _dataProcessor.GetIdentifier(msg.Payload); if (id != null) { _dataSynchronizator.NotifyResult(Encoding.ASCII.GetString(id), msg.Payload); } if (_eventHandler != null) { var rsp = _eventHandler.HandleReceivedData(msg, id != null); if (rsp != null) { _ = SendAsync(rsp); } } }); // bind other events if (_eventHandler != null) { socket.ClientConnectedAction = _eventHandler.HandleClientConnected; socket.ClientConnectionFailureAction = _eventHandler.HandleClientConnectionFailure; socket.MsgSentAction = _eventHandler.HandleSentData; } // connect bool status = await socket.Connect(); // cleanup on failure if (!status) { Interlocked.Exchange(ref _socketClient, null)?.Disconnect(); } // return status Interlocked.Exchange(ref _connecting, null); return(status); }