204 lines
5.5 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>SSE Client Example</title>
<style>
body {
font-family: Arial, sans-serif;
max-width: 800px;
margin: 0 auto;
padding: 20px;
}
.order-tracker {
border: 1px solid #ddd;
border-radius: 4px;
padding: 20px;
margin-top: 20px;
}
.status {
font-weight: bold;
}
.error {
color: red;
}
.events {
margin-top: 20px;
border: 1px solid #eee;
padding: 10px;
height: 300px;
overflow-y: auto;
}
.event {
margin-bottom: 10px;
padding: 5px;
border-bottom: 1px solid #eee;
}
.event-time {
color: #888;
font-size: 0.8em;
}
</style>
</head>
<body>
<h1>SSE Client Example</h1>
<div class="order-tracker">
<h2>Order Tracker</h2>
<div id="status" class="status">Connecting...</div>
<div id="error" class="error" style="display: none;"></div>
<h3>Events</h3>
<div id="events" class="events"></div>
<button id="connect">Connect</button>
<button id="disconnect">Disconnect</button>
</div>
<!-- Include the SSE client library -->
<script src="https://unpkg.com/sse-client@1.0.0/dist/index.js"></script>
<script>
// Get elements
const statusEl = document.getElementById('status');
const errorEl = document.getElementById('error');
const eventsEl = document.getElementById('events');
const connectBtn = document.getElementById('connect');
const disconnectBtn = document.getElementById('disconnect');
// Set up SSE cleanup
SSEClient.setupSSECleanup();
let client = null;
// Add event to the events list
function addEvent(type, data) {
const eventEl = document.createElement('div');
eventEl.className = 'event';
const timeEl = document.createElement('div');
timeEl.className = 'event-time';
timeEl.textContent = new Date().toLocaleTimeString();
const contentEl = document.createElement('div');
contentEl.innerHTML = `<strong>${type}:</strong> ${JSON.stringify(data)}`;
eventEl.appendChild(timeEl);
eventEl.appendChild(contentEl);
eventsEl.appendChild(eventEl);
eventsEl.scrollTop = eventsEl.scrollHeight;
}
// Connect to SSE
function connect() {
// Get auth token from localStorage
const authToken = localStorage.getItem('authToken') || '';
// Order ID (in a real app, this would come from your app state)
const orderId = '123456';
// API base URL
const apiBaseUrl = 'https://api.example.com';
// SSE URL
const sseUrl = `${apiBaseUrl}/events/orders/${orderId}`;
// Update status
statusEl.textContent = 'Connecting...';
errorEl.style.display = 'none';
// Create a new SSE client
client = new SSEClient.SSEClient(sseUrl, {
headers: {
'X-Signed-Auth': authToken
},
debug: true
});
// Listen for order state changes
client.on('orderStateChanged', (event) => {
try {
const data = event.parsedData;
console.log('Order state changed:', data);
// Add event to the events list
addEvent('Order State Changed', data);
// Update status
statusEl.textContent = `Status: ${getStatusText(data.currentState.orderStatus)}`;
// If order is ended, close the connection
if (data.currentState && data.currentState.orderStatus === 1111) {
console.log(`Order ${orderId} ended, closing SSE connection`);
disconnect();
}
} catch (err) {
console.error('Error parsing order state data:', err);
errorEl.textContent = 'Error parsing order state data';
errorEl.style.display = 'block';
}
});
// Listen for connection open
client.on('open', () => {
console.log('SSE connection opened');
addEvent('Connection', 'Opened');
statusEl.textContent = 'Connected';
});
// Listen for connection errors
client.on('error', (event) => {
console.error('SSE connection error:', event.detail);
addEvent('Error', event.detail);
errorEl.textContent = 'SSE connection error';
errorEl.style.display = 'block';
});
// Connect to the SSE endpoint
client.connect();
}
// Disconnect from SSE
function disconnect() {
if (client) {
client.close();
client = null;
// Update status
statusEl.textContent = 'Disconnected';
addEvent('Connection', 'Closed');
}
}
// Helper function to get status text from status code
function getStatusText(status) {
switch (status) {
case 0: return 'Created';
case 10: return 'Accepted';
case 20: return 'Preparing';
case 30: return 'Ready for Pickup';
case 40: return 'Out for Delivery';
case 50: return 'Delivered';
case 1111: return 'Completed';
default: return `Unknown (${status})`;
}
}
// Add event listeners to buttons
connectBtn.addEventListener('click', connect);
disconnectBtn.addEventListener('click', disconnect);
// Connect on page load
connect();
</script>
</body>
</html>