> For the complete documentation index, see [llms.txt](https://vostok.gitbook.io/zookeeper/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://vostok.gitbook.io/zookeeper/basics/connecting-to-a-zookeeper-cluster.md).

# Connecting to a ZooKeeper Cluster

#### Connection State

State of the current connection (do not confuse it with session!) is described by `ConnectionState` property. `ConnectionState` can be one of these: `Connected`, `ConnectedReadonly`, `Disconnected`, `Expired`, `Died`, and `AuthFailed`.

#### Subscribing to Connection State Changes

One can subscribe to the changes of `ConnectionState` using `IObservable OnConnectionStateChanged`. When subscribed to, this sequence immediately produces event with current `ConnectionState`. It *may* produce an `IObserver<T>.OnCompleted` notification when client gets disposed, and *never* produces `IObserver<T>.OnError` notifications.

{% hint style="info" %}
Never call any client methods in observer delegate as it would lead to a deadlock
{% endhint %}

#### Connection State Transitions

Initially, client is created in `Disconnected` state. It will try to establish a working connection upon the first request. To establish a connection immediately, use `ConnectAsync()`/`Connect()` extensions.

Once successfully connected, `ConnectionState` will become either `Connected` or `ConnectedReadonly`. Then, if for some reason client loses connection, `ConnectionState` once again becomes `Disconnected`. `ConnectionState` becomes `Dead` only when client instance is disposed and therefore cannot be used anymore. Client is always connected to a single server node. If that node falls out of quorum, client would try to connect to another node unless `CanBeReadOnly` was set to `true`. In the latter case, state will become `ConnectedReadonly`.

`ConnectionState.Expired` is emitted by server-side when client tries to reconnect to a timed-out session and is not strictly guaranteed to appear every time when session is lost. Given that, a correct way to ensure that ephemeral nodes still exist would be to subscribe onto `ConnectionState` changes and manually probe nodes with `ExistsAsync` every time that `ConnectionState` event is emitted.

#### Connection-Related Properties

<table data-header-hidden><thead><tr><th width="198.59003140929917"></th><th></th></tr></thead><tbody><tr><td><code>SessionId</code></td><td>Returns an <code>int</code> id of an established session when client is in connected state and <code>0</code> otherwise. </td></tr><tr><td><code>SessionTimeout</code></td><td>Returns negotiated session timeout which may differ from <code>Timeout</code> set in <code>ZooKeeperClientSettings</code> upon client creation: ZooKeeper cluster may have configured <code>minSessionTimeout</code> and <code>maxSessionTimeout</code> that limit the possible range of timeout values.</td></tr></tbody></table>
