How to Make Your First Connection
Understand the connect() flow, then run a complete WebSocket connection example in JavaScript, Dart/Flutter, or Python.
Connecting is the first code you write after installing an SDK. This tutorial explains the connection flow conceptually, then walks through a complete, runnable example for each supported language.
What connect() Does
When you call connect(), the SDK performs two phases depending on transport.
Phase 1 — Authentication (All Transports)
- Sends appId, appSecret, and userID to the DNotifier auth endpoint
- Receives an auth token and plan limits
- Sets aiEnabled, messageSizeLimit, and related properties on the client
- If authentication fails (wrong secret, invalid app, plan issue), connect() throws an error.
Phase 2 — Transport Setup
| Transport | What happens after auth |
|---|---|
| ws | Opens a WebSocket to DNotifier, sends a handshake frame with the token, waits for acknowledgment, then sets isConnected = true and calls onConnected |
| http | Skips the persistent socket; sets isConnected = true and calls onConnected immediately after auth |
Constructor Options (Common to All SDKs)
| Option | Required | Description |
|---|---|---|
| appId | Yes | From dashboard |
| secret | Yes | From dashboard |
| transport | Yes | "ws" or "http" |
| userId | Yes | Your end-user or service identifier |
| onConnected | Recommended | Called when ready to send |
| onMessage | Recommended | Called for incoming WebSocket messages |
| onDisconnected | Recommended | Called when the socket closes |
Optional: logs, url (custom WebSocket URL), and platform-specific WebSocket injection (Node.js).
Connection Lifecycle
construct DNotifier
│
▼
connect()
│
├──► HTTP auth (appId + secret + userId)
│ │
│ ▼
│ token + plan limits
│
├──► [ws only] open WebSocket + handshake
│
▼
onConnected()
│
├── send(), sendBinary(), ...
│
▼
onMessage() ◄── incoming frames (ws only)
│
▼
onDisconnected() ◄── socket closed or network lossAfter a Successful Connect
You can read:
- notifier.isConnected — true when ready
- notifier.getPlanLimits() — quotas from your plan
- notifier.aiEnabled — whether AI features are on
- notifier.messageSizeLimit — max message size in bytes
- notifier.authToken — token from the last auth (avoid logging in production)
Prerequisites Checklist
- App created with appId and secret
- Credentials loaded from environment variables
- SDK installed
- Transport chosen — use ws for the first-message walkthrough
What Happens Under the Hood
- SDK authenticates over HTTPS with your credentials
- Auth returns a token and plan limits
- WebSocket opens to the production host (WSS)
- Client completes handshake with the token
- Server acknowledges → onConnected fires
Common Errors
| Error | Likely cause |
|---|---|
| appId, secret, transport, and userId are required | Missing constructor field |
| Authentication Failed | Wrong secret or invalid appId |
| WebSocket errors in Node | Forgot WebSocketImpl: WebSocket |
| Immediate disconnect | Network/firewall blocking wss:// |
JavaScript / TypeScript
This guide connects a DNotifier client over WebSocket from Node.js or the browser.
Complete Example (Node.js)
import WebSocket from "ws";
import { DNotifier } from "@dnotifier-realtime/dnotifier";
const notifier = new DNotifier({
appId: process.env.DNOTIFIER_APP_ID,
secret: process.env.DNOTIFIER_SECRET,
transport: "ws",
userId: "user-alice",
WebSocketImpl: WebSocket,
onConnected: () => {
console.log("Connected — ready to send messages");
console.log("Plan limits:", notifier.getPlanLimits());
},
onMessage: (msg) => {
console.log("Incoming from:", msg.metadata.sender);
console.log("Payload:", msg.payload.toJSON());
},
onDisconnected: () => {
console.log("Disconnected");
},
});
async function main() {
try {
await notifier.connect();
console.log("isConnected:", notifier.isConnected);
console.log("messageSizeLimit:", notifier.messageSizeLimit);
} catch (err) {
console.error("Connect failed:", err.message);
process.exit(1);
}
}
main();Save as connect.js, set environment variables, and run:
export DNOTIFIER_APP_ID=your-app-id
export DNOTIFIER_SECRET=your-app-secret
node connect.jsExpected Output
Connected — ready to send messages
Plan limits: { aiEnabled: true, messagesHardLimit: ..., ... }
isConnected: true
messageSizeLimit: 32768Complete Example (Browser)
Omit WebSocketImpl — the browser provides WebSocket globally:
import { DNotifier } from "@dnotifier-realtime/dnotifier";
const notifier = new DNotifier({
appId: import.meta.env.VITE_DNOTIFIER_APP_ID,
secret: import.meta.env.VITE_DNOTIFIER_SECRET,
transport: "ws",
userId: "user-alice",
onConnected: () => console.log("Connected"),
onMessage: (msg) => console.log(msg.payload.toJSON()),
onDisconnected: () => console.log("Disconnected"),
});
await notifier.connect();Complete Example (HTTP Transport)
Use HTTP when you only need AI/RAG/workflows — no persistent socket:
import { DNotifier } from "@dnotifier-realtime/dnotifier";
const notifier = new DNotifier({
appId: process.env.DNOTIFIER_APP_ID,
secret: process.env.DNOTIFIER_SECRET,
transport: "http",
userId: "user-alice",
onConnected: () => console.log("Authenticated via HTTP"),
onMessage: () => {},
onDisconnected: () => {},
});
await notifier.connect();
// Ready for sendAI(), search(), runWorkflow(), etc.TypeScript Variant
import WebSocket from "ws";
import { DNotifier } from "@dnotifier-realtime/dnotifier";
const notifier = new DNotifier({
appId: process.env.DNOTIFIER_APP_ID!,
secret: process.env.DNOTIFIER_SECRET!,
transport: "ws",
userId: "user-alice",
WebSocketImpl: WebSocket,
onConnected: (): void => {
const limits = notifier.getPlanLimits();
console.log("AI enabled:", limits?.aiEnabled);
},
onMessage: (msg): void => {
const body = msg.payload.toJSON() as { type?: string; text?: string };
if (body?.type === "text") {
console.log(body.text);
}
},
onDisconnected: (): void => {},
});
await notifier.connect();Common Errors
| Error | Likely cause |
|---|---|
| appId, secret, transport, and userId are required | Missing constructor field |
| Authentication Failed | Wrong secret or invalid appId |
| WebSocket errors in Node | Forgot WebSocketImpl: WebSocket |
| Immediate disconnect | Network/firewall blocking wss:// |
What Happens Under the Hood
- SDK authenticates over HTTPS with your credentials
- Auth returns a token and plan limits
- WebSocket opens to the production host (WSS)
- Client completes handshake with the token
- Server acknowledges → onConnected fires
Dart / Flutter
This guide connects a DNotifier client over WebSocket from Dart or Flutter.
Complete Example
import 'package:dnotifier/dnotifier.dart';
Future<void> main() async {
final notifier = DNotifier(
appId: 'your-app-id',
secret: 'your-app-secret',
transport: 'ws',
userId: 'user-alice',
onConnected: () {
print('Connected — ready to send messages');
final limits = notifier.getPlanLimits();
print('Plan limits: $limits');
},
onMessage: (DNotifierMessage msg) {
print('Incoming from: ${msg.metadata.sender}');
print('Payload: ${msg.payload.toJSON()}');
},
onDisconnected: ({code, reason}) {
print('Disconnected: code=$code reason=$reason');
},
);
try {
await notifier.connect();
print('isConnected: ${notifier.isConnected}');
print('messageSizeLimit: ${notifier.messageSizeLimit}');
} catch (e) {
print('Connect failed: $e');
}
}Replace 'your-app-id' and 'your-app-secret' with values from the dashboard, or load them from environment defines.
Run in a Pure Dart Project
dart run bin/connect.dartRun in Flutter
flutter runExpected Console Output
Connected — ready to send messages
Plan limits: Instance of 'DNotifierPlanLimits'
isConnected: true
messageSizeLimit: 32768Flutter Widget Example
import 'package:flutter/material.dart';
import 'package:dnotifier/dnotifier.dart';
class DNotifierScreen extends StatefulWidget {
const DNotifierScreen({super.key});
@override
State<DNotifierScreen> createState() => _DNotifierScreenState();
}
class _DNotifierScreenState extends State<DNotifierScreen> {
late final DNotifier _notifier;
String _status = 'Connecting…';
@override
void initState() {
super.initState();
_notifier = DNotifier(
appId: const String.fromEnvironment('DNOTIFIER_APP_ID'),
secret: const String.fromEnvironment('DNOTIFIER_SECRET'),
transport: 'ws',
userId: 'user-alice',
onConnected: () => setState(() => _status = 'Connected'),
onMessage: (msg) {
debugPrint('Message: ${msg.payload.toJSON()}');
},
onDisconnected: ({code, reason}) {
setState(() => _status = 'Disconnected');
},
);
_notifier.connect().catchError((e) {
setState(() => _status = 'Error: $e');
});
}
@override
void dispose() {
_notifier.disconnect();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('DNotifier')),
body: Center(child: Text(_status)),
);
}
}HTTP Transport Example
For AI/RAG/workflows without a persistent socket:
final notifier = DNotifier(
appId: 'your-app-id',
secret: 'your-app-secret',
transport: 'http',
userId: 'user-alice',
onConnected: () => print('Authenticated via HTTP'),
);
await notifier.connect();
// Ready for sendAI(), search(), runWorkflow(), etc.Common Errors
| Error | Likely cause |
|---|---|
| ArgumentError: appId, secret, and userId are required | Empty constructor argument |
| Exception: Authentication failed | Wrong secret or appId |
| StateError: Not connected | Called send() before connect() finished |
| Socket errors on device | Network or certificate issues |
What Happens Under the Hood
- SDK sends credentials to the DNotifier auth endpoint
- Auth returns token and plan limits
- WebSocket connects to the DNotifier realtime endpoint
- Client sends handshake with token
- Server acknowledges → onConnected callback runs
Python
This guide connects a DNotifier client over WebSocket from Python.
Complete Example
import asyncio
from dnotifier import DNotifier
async def main():
notifier = DNotifier(
app_id="your-app-id",
secret="your-app-secret",
transport="ws",
user_id="user-alice",
on_connected=lambda: print("Connected — ready to send messages"),
on_message=lambda msg: print(
f"Incoming from: {msg.metadata.sender}\nPayload: {msg.payload.to_json()}"
),
on_disconnected=lambda code=None, reason=None: print(
f"Disconnected: code={code} reason={reason}"
),
)
try:
await notifier.connect()
print(f"is_connected: {notifier.is_connected}")
print(f"message_size_limit: {notifier.message_size_limit}")
limits = notifier.get_plan_limits()
print(f"Plan limits: {limits}")
except Exception as e:
print(f"Connect failed: {e}")
asyncio.run(main())Replace 'your-app-id' and 'your-app-secret' with values from the dashboard, or load them from environment variables.
Run
python connect.pyExpected Console Output
Connected — ready to send messages
is_connected: True
message_size_limit: 32768
Plan limits: DNotifierPlanLimits(...)FastAPI Lifespan Example
import os
from contextlib import asynccontextmanager
from fastapi import FastAPI
from dnotifier import DNotifier
notifier: DNotifier | None = None
@asynccontextmanager
async def lifespan(app: FastAPI):
global notifier
notifier = DNotifier(
app_id=os.environ["DNOTIFIER_APP_ID"],
secret=os.environ["DNOTIFIER_SECRET"],
transport="ws",
user_id="user-alice",
on_connected=lambda: print("Connected"),
on_message=lambda msg: print(msg.payload.to_json()),
)
await notifier.connect()
yield
await notifier.disconnect()
app = FastAPI(lifespan=lifespan)HTTP Transport Example
For AI/RAG/workflows without a persistent socket:
notifier = DNotifier(
app_id="your-app-id",
secret="your-app-secret",
transport="http",
user_id="user-alice",
on_connected=lambda: print("Authenticated via HTTP"),
)
await notifier.connect()
# Ready for send_ai(), search(), run_workflow(), etc.Common Errors
| Error | Likely cause |
|---|---|
| ValueError: app_id, secret, transport, and user_id are required | Empty constructor argument |
| RuntimeError: Authentication failed | Wrong secret or app_id |
| RuntimeError: Not connected | Called send() before connect() finished |
| Connection errors | Network or certificate issues |
What Happens Under the Hood
- SDK sends credentials to the DNotifier auth endpoint (api.dnotifier.com)
- Auth returns token and plan limits
- WebSocket connects to the DNotifier realtime endpoint
- Client sends handshake with token
- Server acknowledges → on_connected callback runs
Next step
After you connect successfully, you're ready to send your first 1:1 message: How to send and receive your first message.
Watch: How to Make Your First Connection
Same steps as above — use whichever format you prefer.
DNotifier Tutorial