/// <summary>
        /// Connect to canal server.
        /// </summary>
        /// <returns></returns>
        public async Task ConnectAsync()
        {
            //get canal address from zk
            await ConnectToZkAsync();

            var nodeData = await _zk.GetDataAsync(ZK_SERVER_RUNNING_NODE);

            var runningInfo = JsonConvert.DeserializeObject <CanalServerRunningInfo>(Encoding.UTF8.GetString(nodeData));

            _logger.LogInformation($"get canal address from zookeeper success: {runningInfo.Address}");

            //connect to canal
            _currentConn = new SimpleCanalConnection(CopyOptions(runningInfo), _loggerFactory.CreateLogger <SimpleCanalConnection>());
            await _currentConn.ConnectAsync();

            _serverRunningNodeReCreated = false;

            var localIp = _currentConn.GetLocalEndPoint().ToString();

            _clientRunningInfo = new CanalClientRunningInfo()
            {
                Active = true, Address = localIp, ClientId = _options.ClientId
            };
            _ = GetZkLockAsync(_clientRunningInfo);
            await _completionSource.Task;

            _logger.LogInformation("Ready to use!");
        }