Client Examples
DataStream includes interactive client pages to visualize and compare all streaming protocols in real-time.
All clients are deployed and running at https://datastream.andrebassi.com.br β no setup required!
Live Clients (Online)β
All clients are available online at https://datastream.andrebassi.com.br:
| Client | Online URL | Protocol |
|---|---|---|
| Main Dashboard | datastream.andrebassi.com.br | All |
| WebSocket | /websocket.html | WebSocket |
| NATS | /nats.html | NATS WebSocket |
| SSE | /sse.html | SSE |
| WebTransport | /webtransport.html | QUIC/HTTP3 |
| REST API | /rest-api.html | HTTP Polling |
| Protocol Comparison | /test.html | All |
Available Clientsβ
| Client | Local URL | Protocol | Description |
|---|---|---|---|
| Main Dashboard | / or /index.html | All | Overview of all 5 protocols ranked by speed |
| WebSocket | /websocket.html | WebSocket | Real-time bidirectional streaming |
| NATS | /nats.html | NATS WebSocket | Direct broker connection |
| SSE | /sse.html | Server-Sent Events | Unidirectional server push |
| WebTransport | /webtransport.html | QUIC/HTTP3 | Ultra-low latency streaming |
| REST API | /rest-api.html | HTTP Polling | Traditional polling approach |
| Protocol Comparison | /test.html | All | Side-by-side comparison |
Main Dashboardβ
URL: http://localhost:3000/
The main dashboard provides an overview of all available streaming protocols, ranked by speed:
#1 WebTransport (QUIC) β 0.5-2ms latency
#2 NATS WebSocket β 0.5-2ms latency
#3 WebSocket β 1-5ms latency
#4 SSE β 10-50ms latency
#5 REST API β 50-200ms latency
Featuresβ
- Protocol cards with descriptions and use cases
- Quick access links to individual clients
- Pros and cons for each protocol
- When to use recommendations
WebSocket Clientβ
URL: http://localhost:3000/websocket.html
Interactive WebSocket client connecting to /ws/{game} endpoints.
Featuresβ
- Real-time connection status indicator
- Automatic reconnection on disconnect
- Game cards with live updates
- History of recent results
- Flash animation on new data
How It Worksβ
// Connects to each game's WebSocket endpoint
const ws = new WebSocket(`ws://${host}/ws/crash`);
ws.onmessage = (event) => {
const result = JSON.parse(event.data);
updateCard(result);
};
ws.onclose = () => {
// Auto-reconnect after 3 seconds
setTimeout(reconnect, 3000);
};
NATS WebSocket Clientβ
URL: http://localhost:3000/nats.html
Direct connection to NATS message broker, bypassing the backend.
Featuresβ
- Connects to
ws://localhost:8443(NATS WebSocket port) - Subscribes to
rounds.game.*wildcard pattern - Per-message latency tracking
- Message count statistics
- All games in a single subscription
How It Worksβ
import { connect, StringCodec } from 'nats.ws';
// Direct broker connection
const nc = await connect({ servers: 'ws://localhost:8443' });
const sc = StringCodec();
// Wildcard subscription for all games
const sub = nc.subscribe('rounds.game.*');
for await (const msg of sub) {
const data = JSON.parse(sc.decode(msg.data));
const game = msg.subject.split('.').pop();
updateUI(game, data);
}
Advantagesβ
- Lowest latency (direct to broker)
- Wildcard subscriptions
- All games in one connection
- No backend hop
SSE Clientβ
URL: http://localhost:3000/sse.html
Server-Sent Events streaming with automatic reconnection.
Featuresβ
- Native browser reconnection
- Initial event with latest data
- Connection status indicator
- Game cards with history
- Works through proxies/CDNs
How It Worksβ
// Native browser API
const sse = new EventSource('/sse/crash');
// Initial event - last known result
sse.addEventListener('initial', (e) => {
const result = JSON.parse(e.data);
updateCard(result, false); // Don't add to history
});
// New results
sse.addEventListener('message', (e) => {
const result = JSON.parse(e.data);
updateCard(result, true); // Add to history
});
// Auto-reconnection is built-in!
sse.onerror = () => console.log('Reconnecting...');
Event Typesβ
| Event | Description | Trigger |
|---|---|---|
initial | Last known result | On connection |
message | New game result | On data change |
| Heartbeat | Keep-alive comment | Every 15 seconds |
WebTransport Clientβ
URL: http://localhost:3000/webtransport.html
Cutting-edge QUIC/HTTP3 streaming for ultra-low latency.
Featuresβ
- QUIC-based transport
- Datagram support (UDP-like)
- Stream multiplexing
- Latency tracking
- Browser support detection
How It Worksβ
const WT_URL = 'https://datastream.andrebassi.com.br:4433/wt';
// Create WebTransport connection
const transport = new WebTransport(WT_URL);
await transport.ready;
// Read datagrams (unreliable, low latency)
const reader = transport.datagrams.readable.getReader();
while (true) {
const { value, done } = await reader.read();
if (done) break;
const text = new TextDecoder().decode(value);
const data = JSON.parse(text);
handleMessage(data);
}
Browser Supportβ
| Browser | Support |
|---|---|
| Chrome 97+ | Yes |
| Edge 97+ | Yes |
| Firefox 114+ | Yes |
| Safari | No |
REST API Clientβ
URL: http://localhost:3000/rest-api.html
Traditional HTTP polling approach for maximum compatibility.
Featuresβ
- 2-second polling interval
- Works everywhere (universal)
- Cacheable responses
- No persistent connection
- Good for history queries
How It Worksβ
const POLL_INTERVAL = 2000; // 2 seconds
async function poll() {
// Fetch latest for each game
const games = await fetch('/api/games').then(r => r.json());
for (const game of games) {
const latest = await fetch(`/api/latest/${game.slug}`);
const result = await latest.json();
updateCard(result);
}
}
// Start polling loop
setInterval(poll, POLL_INTERVAL);
Endpoints Usedβ
| Endpoint | Purpose |
|---|---|
GET /api/games | List available games |
GET /api/latest/{game} | Get latest result |
GET /api/history/{game} | Get history (initial load) |
Protocol Comparison Clientβ
URL: http://localhost:3000/test.html
Side-by-side comparison of WebSocket, SSE, and WebTransport.
Featuresβ
- Connect/disconnect buttons for each protocol
- Message count per protocol
- Average latency tracking
- Live message logs
- Comparison table with features
Metrics Trackedβ
| Metric | Description |
|---|---|
| Messages | Total messages received |
| Avg Latency | Average message latency (ms) |
| Status | Connection state |
Comparison Tableβ
The demo includes a feature comparison:
| Feature | WebSocket | SSE | WebTransport |
|---|---|---|---|
| Direction | Bidirectional | ServerβClient | Bidirectional |
| Protocol | TCP | HTTP | UDP (QUIC) |
| Latency | 1-5ms | 10-50ms | 0.5-2ms |
| Auto-reconnect | Manual | Native | Manual |
| Multiple streams | No | No | Yes |
| Datagrams | No | No | Yes |
| Browser support | Universal | No IE | Chrome/Firefox |
Running the Clientsβ
Prerequisitesβ
# 1. Start infrastructure
task infra:up
# 2. Start consumer (terminal 1)
task consumer:run
# 3. Start backend (terminal 2)
task backend:run
Access Clientsβ
# Open main dashboard
open http://localhost:3000
# Or specific demos
open http://localhost:3000/websocket.html
open http://localhost:3000/nats.html
open http://localhost:3000/sse.html
open http://localhost:3000/webtransport.html
open http://localhost:3000/rest-api.html
open http://localhost:3000/test.html
Generate Test Dataβ
# Single round
task db:simulate
# 100 rounds
task db:generate
# Continuous simulation (every 2 seconds)
watch -n 2 'task db:simulate'
Testing Tipsβ
WebSocketβ
# Browser console
const ws = new WebSocket('ws://localhost:3000/ws/crash');
ws.onmessage = (e) => console.log(JSON.parse(e.data));
SSEβ
# Terminal (works with curl!)
curl -N http://localhost:3000/sse/crash
NATSβ
# Requires nats-cli
nats sub "rounds.game.*"
WebTransportβ
WebTransport requires:
- Chrome 97+ or Firefox 114+
- HTTPS with valid certificate
- UDP port accessible