pub.dev License: MIT Platform

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 via emitter.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.1

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';

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

Note: The adk-services.json file 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 of AppConfigLoader and AuthService.

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 KeyPair. 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']),
);

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 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.

Libraries

art_adk