> For the complete documentation index, see [llms.txt](https://dnotifier.gitbook.io/product-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://dnotifier.gitbook.io/product-docs/realtime-communication/connection-lifecycle.md).

# Connection lifecycle

A DNotifier realtime client moves through **authentication**, **WebSocket handshake** (when using `ws`), **active messaging**, and **disconnect**. Understanding this lifecycle helps you wire `onConnected`, `onMessage`, and `onDisconnected` correctly.

***

## Lifecycle diagram

```
  construct DNotifier({ transport: "ws", userId, ... })
         │
         ▼
    await connect()
         │
         ├──► HTTPS auth → production API host
         │         │
         │         ▼
         │    token + plan limits
         │
         ├──► [ws only] open WebSocket + handshake
         │
         ▼
   onConnected()
   isConnected === true
         │
         ├── send(), sendBinary(), fetchChatHistory(), ...
         │
         ▼
   onMessage()  ◄── incoming frames (ws only)
         │
         ▼
   disconnect() or network loss
         │
         ▼
   onDisconnected({ code, reason })
   isConnected === false
```

***

## Phase 1 — Authentication

All transports authenticate the same way at `connect()`:

1. SDK sends `appId`, `appSecret`, and `userID` to the DNotifier auth endpoint
2. Server returns an **auth token** and **plan limits**
3. Client sets `aiEnabled`, `messageSizeLimit`, and related properties

If authentication fails (wrong secret, invalid app, plan issue), `connect()` throws.

{% hint style="info" %}
Production auth uses **`api.dnotifier.com`**. You rarely need to configure this — SDKs default to the production host. Use the optional `url` constructor parameter only when DNotifier provides a custom WebSocket endpoint.
{% endhint %}

***

## Phase 2 — WebSocket handshake (`transport: "ws"`)

After auth succeeds:

1. SDK opens a WebSocket to the DNotifier realtime endpoint
2. Sends a handshake frame containing the auth token
3. Waits for server acknowledgment
4. Sets `isConnected = true` and invokes `onConnected`

Until `onConnected` fires, do not call `send()` or other realtime methods — they require an active connection.

***

## Phase 3 — Active session

While connected you can:

| Action                       | Method               |
| ---------------------------- | -------------------- |
| Send text or structured data | `send()`             |
| Send raw binary              | `sendBinary()`       |
| Request chat history         | `fetchChatHistory()` |
| Read plan limits             | `getPlanLimits()`    |
| Check connection state       | `isConnected`        |

Incoming messages always flow through the **`onMessage`** callback registered at construction time.

***

## Phase 4 — Disconnect

Disconnect can happen when:

* You call `disconnect()` explicitly
* The network drops or the server closes the socket
* An unrecoverable transport error occurs

The SDK invokes **`onDisconnected`** with optional `code` and `reason`. After disconnect, `isConnected` is `false` and sends will throw until you `connect()` again.

{% hint style="warning" %}
DNotifier does **not** auto-reconnect. Your app should listen to `onDisconnected`, show offline state, and call `connect()` when the user or your retry policy allows. See [Error handling & reconnection](/product-docs/realtime-communication/error-handling.md).
{% endhint %}

***

## Properties after connect

| Property           | Description                                                   |
| ------------------ | ------------------------------------------------------------- |
| `isConnected`      | `true` when ready to send (ws) or authenticated (http)        |
| `aiEnabled`        | Whether AI is enabled for the current plan                    |
| `authToken`        | Token from last successful auth — avoid logging in production |
| `messageSizeLimit` | Max message size in bytes before chunking                     |

```js
await notifier.connect();
console.log(notifier.isConnected);
console.log(notifier.messageSizeLimit);
const limits = notifier.getPlanLimits();
```

Dart equivalent:

```dart
await notifier.connect();
print(notifier.isConnected);
print(notifier.messageSizeLimit);
final limits = notifier.getPlanLimits();
```

***

## HTTP transport note

With `transport: "http"`, Phase 2 is skipped — there is no persistent socket. `connect()` authenticates and sets `isConnected = true` immediately. Realtime `send()` and `onMessage` are not the primary use case for HTTP; use **`ws`** for live messaging.

→ [Choose your transport](/product-docs/getting-started/choose-transport.md)

***

## Next steps

* [Send & receive text](/product-docs/realtime-communication/send-and-receive.md)
* [Error handling & reconnection](/product-docs/realtime-communication/error-handling.md)
* [Your first connection](/product-docs/getting-started/first-connection.md)
