Skip to main content

max / makenotwork

2.5 KB · 88 lines History Blame Raw
1 # SyncKit SSE Push Notifications
2
3 SyncKit provides a Server-Sent Events (SSE) endpoint that notifies connected clients in real time when new data is available. Instead of polling, your app can subscribe to a persistent connection and pull only when something changes.
4
5 ## Endpoint
6
7 ```
8 GET /api/sync/subscribe?app_id={app_id}
9 Authorization: Bearer <token>
10 ```
11
12 Requires a valid SyncKit JWT token. The `app_id` query parameter specifies which sync app to subscribe to.
13
14 ## Event Format
15
16 When another device pushes changes, all other connected devices for the same app and user receive a `changed` event:
17
18 ```
19 event: changed
20 data:
21 ```
22
23 The event carries no payload (data is always E2E encrypted and never sent over SSE). On receiving `changed`, initiate a pull to fetch actual changes.
24
25 ## Keepalive
26
27 The server sends a comment line every 30 seconds to keep the connection alive and prevent proxy timeouts:
28
29 ```
30 : keepalive
31 ```
32
33 This is a standard SSE comment and is ignored by conforming clients.
34
35 ## Client Integration
36
37 ### Basic Flow
38
39 1. Authenticate and obtain a SyncKit JWT token
40 2. Open an SSE connection to `/api/sync/subscribe?app_id={app_id}`
41 3. On receiving a `changed` event, call the pull endpoint to fetch new changes
42 4. Reconnect on connection drop (most SSE libraries handle this automatically)
43
44 ### With the Rust SDK
45
46 The `synckit-client` crate provides `SyncNotifyStream` for SSE integration:
47
48 ```rust
49 let stream = client.subscribe_notifications().await?;
50
51 // In your sync loop:
52 while let Some(notification) = stream.next().await {
53 match notification {
54 SyncNotification::Changed => {
55 client.pull().await?;
56 }
57 SyncNotification::Keepalive => {}
58 }
59 }
60 ```
61
62 The SDK handles reconnection, keepalive parsing, and token refresh automatically.
63
64 ### Selective Sync
65
66 Combine SSE notifications with `PullFilter` to pull only specific tables or time ranges:
67
68 ```rust
69 let filter = PullFilter::new()
70 .table("tasks")
71 .since(last_sync_time);
72
73 let changes = client.pull_filtered(filter).await?;
74 ```
75
76 This reduces bandwidth and processing when your app only needs a subset of changes.
77
78 ## Design Notes
79
80 - One SSE connection per (app, user) pair
81 - The broadcast channel buffers up to 16 messages. If a client falls behind, missed events are skipped. The next pull will catch up regardless.
82 - SSE works through standard HTTP proxies and load balancers. The 30-second keepalive stays within common proxy timeout defaults.
83
84 ## See Also
85
86 - [SyncKit Cloud Sync]./synckit.md: Full sync API reference
87 - [OAuth2 PKCE]./oauth.md: Authentication for SyncKit apps
88