art_adk 1.0.0
art_adk: ^1.0.0 copied to clipboard
A Flutter SDK for ARealtimeTech (ART) — real-time WebSocket messaging, channel subscriptions, presence, encrypted channels, and CRDT shared objects.
Flutter SDK for ART - A Realtime Tech communication — a real-time messaging platform offering WebSocket-based channels, presence tracking, encrypted communication, shared object channels.
Features #
- WebSocket Connection Management — connect, reconnect, and disconnect with built-in reliability
- Channel Subscription — subscribe to broadcast, targeted, group, encrypted, and shared-object channels
- Push Messages — send structured payloads to channels with optional targeted delivery
- Listen & Bind — capture every event with
listen()or react to specific events viaemitter.on() - User Presence — track online users in real time
- Encrypted Channels — end-to-end encrypted messaging
- Interceptors — pre-process or post-process messages with custom logic
- Shared Object Channels — CRDT-backed collaborative data structures
Installation #
Follow the steps to set up and start using the Flutter ADK in your project.
1. Install the ADK Package #
Add the ADK to your Flutter project's pubspec.yaml:
dependencies:
art_adk: ^1.0.0
Then run:
flutter pub get
2. Import the ADK into your project #
Import the ADK in your Dart files to use the features provided by ART:
import 'package:art_adk/art_adk.dart';
Everything is asynchronous by default — Flutter uses Future / async / await.
3. Generate Client Secret #
Once you have access to the ART Live Dashboard, generate the Client Secret and place the credential file at assets/adk-services.json in your project. The JSON looks like this:
{
"Client-ID": "xxxxxxxxxx",
"Client-Secret": "xxxxxxxxxxx",
"Org-Title": "YOUR_ORG",
"ProjectKey": "YOUR_PROJECT_KEY",
"Environment": "YOUR_ENV_NAME"
}
Register the asset in your pubspec.yaml:
flutter:
assets:
- assets/adk-services.json
⚠️ Important: Add
assets/adk-services.jsonto.gitignore. Never commit credentials to version control.
📝 Note: The
adk-services.jsonfile needs to be updated with your ProjectKey and Environment, manually. To learn how to obtain these values, see the Workspace and Project guide.
4. Get Passcode #
Before authenticating, obtain a passcode for the user. This passcode is used as the auth token when initialising the ADK:
import 'package:art_adk/art_adk.dart';
final credentials = await AppConfigLoader.loadCredentials();
final passcode = await AuthService.connectWithPasscode(
username: 'your_username',
firstName: 'first_name',
lastName: 'last_name',
credentials: credentials,
);
📝 See the
example/folder for reference implementations ofAppConfigLoaderandAuthService.
5. Authenticate #
Once the client credentials are loaded and you have a passcode, initialise the ADK and connect to the server:
final updatedCreds = credentials.copyWith(accessToken: passcode);
final config = AdkConfig(
uri: 'ws.arealtimetech.com', // Replace with your ART server WebSocket URI
authToken: passcode, // Use the passcode from step 4
getCredentials: () => updatedCreds,
);
final adk = Adk(adkConfig: config);
// Listen to lifecycle events
adk.on('connection', (_) => debugPrint('✅ Connected'));
adk.on('close', (_) => debugPrint('❌ Disconnected'));
await adk.connect();
For short-lived workflows, wrap connect / disconnect in a try / finally:
final adk = Adk(adkConfig: config);
try {
await adk.connect();
// Your logic here
} finally {
await adk.disconnect();
}
6. Subscribe to Channel #
A Channel is a communication pathway that provides passage for data transfer. Subscribing to a channel lets you use real-time messaging in your application:
final subscription = await adk.subscribe(channel: 'your-channel-name');
The return type is BaseSubscription. For shared-object (CRDT) channels, downcast to LiveObjSubscription to access the CRDT API:
if (subscription is LiveObjSubscription) {
// CRDT-enabled channel: state(), query(), flush()…
}
7. Push Messages #
Messages are pushed to a channel using the push() method. This method allows you to send various event types with associated data, and optionally target specific users within the channel for more granular delivery:
// Define the message payload
final payload = <String, dynamic>{'content': 'Hello from ART ADK!'};
// Optionally define specific target users within the channel
final targetUsers = <String>['username1', 'username2'];
try {
await subscription.push(
event: 'message',
data: payload,
options: PushConfig(to: targetUsers), // target specific recipients
);
debugPrint('Message acknowledged by ART');
} catch (error) {
debugPrint('Failed to push message: $error');
}
🔒 Important: Secure and Targeted channels require exactly one recipient in
PushConfig(to: [...]).
8. Listen to All Events and Messages #
Bind handlers to events on the subscription's emitter. This delivers every incoming payload for the bound event type:
subscription.emitter.on('message', (dynamic data) {
debugPrint('Received: $data');
});
To listen to every event on a default channel, cast to Subscription and call listen():
if (subscription is Subscription) {
subscription.listen((Map<String, dynamic> data) {
debugPrint("Event '${data['event']}' → ${data['content']}");
});
}
User Presence #
Track users online in a channel in real time:
final cancel = await subscription.fetchPresence(
callback: (List<String> users) {
debugPrint('👥 Online: $users');
},
);
// Later, when you no longer need updates:
await cancel();
📝 Note: Enable presence tracking when creating the channel on the ART Dashboard.
Encrypted Channels #
Secure channels require a Curve25519 key pair. Generate one after connecting:
await adk.generateKeyPair();
Once generated, encryption and decryption on secure channels is automatic when you push or receive messages. Secure channels require exactly one recipient per push.
final secure = await adk.subscribe(channel: 'YOUR_ENCRYPTED_CHANNEL');
await secure.push(
event: 'message',
data: <String, dynamic>{'content': 'Hello privately'},
options: PushConfig(to: <String>['recipient-username']),
);
📝 Note: Private keys are kept in memory only. Persist with
flutter_secure_storageif you need session continuity across restarts.
Shared Object Channels (CRDT) #
CRDT-backed channels let multiple clients edit the same data structure with automatic conflict resolution.
final sub = await adk.subscribe(channel: 'YOUR_SHARED_OBJECT_CHANNEL');
if (sub is LiveObjSubscription) {
// Write
sub.state()['document']['title'].set('My Doc');
await sub.flush();
// Observe
final query = sub.query(path: 'document');
await query.listen((dynamic data) {
debugPrint('Doc changed: $data');
});
}
Supported operations on arrays: push, unshift, pop, removeAt, splice.
Interceptors #
Plug custom logic into the message pipeline:
await adk.intercept(
interceptor: 'my-interceptor',
fn: (
Map<String, dynamic> payload,
void Function(dynamic data) resolve,
void Function(String error) reject,
) {
debugPrint('Intercepted: $payload');
resolve(payload); // or reject('reason')
},
);
🔒 Important: Encrypted channel types cannot be intercepted — ART preserves complete privacy on those channels.
Connection Lifecycle #
adk.on('connection', (data) {
if (data is ConnectionDetail) {
debugPrint('connectionId: ${data.connectionId}');
}
});
adk.on('close', (reason) => debugPrint('Closed: $reason'));
// Manual controls
adk.pause(); // temporarily stop
await adk.resume(); // bring back online
await adk.disconnect(); // full teardown
adk.getState() returns one of: 'connected', 'retrying', 'paused', 'stopped'.
Example Usage #
It demonstrates:
- Loading credentials from an asset JSON
- Passcode authentication
- Subscribing to secure, default, and CRDT channels
- Sending targeted messages
- Live multi-user cursor positions via shared objects
- Adding and removing interceptors at runtime
Run it:
cd example
flutter run
API Reference #
| Class | Purpose |
|---|---|
Adk |
Top-level SDK facade — connect, subscribe, intercept, key management |
CredentialStore |
Immutable holder for org/project/client credentials |
BaseSubscription |
Base channel subscription — push, fetchPresence, unsubscribe |
Subscription |
Default / secure channel with emitter.on() and listen() |
LiveObjSubscription |
CRDT-backed shared-object channel with state() / query() / flush() |
CRDTProxy |
Chainable CRDT state accessor (state()['a']['b'].set(...)) |
PushConfig |
Push options — to: List<String> for targeted delivery |
KeyPairType |
Curve25519 keypair for secure channels |
ConnectionDetail |
Emitted on 'connection' — contains connectionId, instanceId, etc. |
Documentation #
Full documentation is available at docs.arealtimetech.com/docs/adk.
| Topic | Link |
|---|---|
| Overview | ADK Overview |
| Installation | Flutter Installation |
| Publish & Subscribe | Pub/Sub Docs |
| Connection Management | Connection Docs |
| User Presence | Presence Docs |
| Encrypted Channels | Encryption Docs |
| Shared Object Channels | Shared Object Docs |
| Interceptors | Interceptor Docs |
License #
MIT License. See LICENSE for details.