A todo and personal organisation app
WebSocket Sync#
Overview#
Toadist uses WebSockets for real-time synchronization between clients.
Connection#
Client Connection#
final client = WebSocketClient(
serverUrl: 'ws://localhost:8082/ws',
authToken: accessToken,
);
await client.connect();
Server Endpoint#
ws://localhost:8080/ws
Requires Authorization header or token query parameter.
Message Protocol#
All messages are JSON objects with a type field.
Client → Server#
Subscribe#
{
"type": "subscribe",
"userId": "uuid"
}
Ping#
{
"type": "ping"
}
Server → Client#
Pong#
{
"type": "pong"
}
Noot Created#
{
"type": "noot_created",
"nootId": "uuid",
"userId": "uuid",
"timestamp": "2026-01-30T12:00:00Z"
}
Noot Updated#
{
"type": "noot_updated",
"nootId": "uuid",
"userId": "uuid",
"timestamp": "2026-01-30T12:00:00Z"
}
Noot Deleted#
{
"type": "noot_deleted",
"nootId": "uuid",
"userId": "uuid",
"timestamp": "2026-01-30T12:00:00Z"
}
Client Handling#
client.messages.listen((message) {
final data = jsonDecode(message);
switch (data['type']) {
case 'noot_created':
case 'noot_updated':
// Fetch updated noot from API
await fetchNoot(data['nootId']);
break;
case 'noot_deleted':
// Remove from local pool
nootPool.remove(data['nootId']);
break;
}
});
Auto-Reconnect#
The WebSocketClient automatically reconnects on disconnect:
WebSocketClient(
serverUrl: url,
authToken: token,
reconnectDelay: Duration(seconds: 5),
maxReconnectAttempts: 10,
);
Server Broadcasting#
The server broadcasts events to all connected clients for a user:
// In API handlers after mutations
WebSocketHandler.broadcast(
userId: userId,
event: {
'type': 'noot_updated',
'nootId': noot.id,
'timestamp': DateTime.now().toIso8601String(),
},
);
Connection Lifecycle#
- Client connects with auth token
- Server validates token
- Client subscribes to user events
- Server adds to broadcast group
- Client sends periodic pings
- Server responds with pongs
- On disconnect, server removes from group
- Client auto-reconnects if unexpected
Error Handling#
| Error | Response |
|---|---|
| Invalid token | Connection closed with 401 |
| Malformed message | Ignored, logged |
| Connection timeout | Client reconnects |