Documentation Index
Fetch the complete documentation index at: https://docs.bookovia.com/llms.txt
Use this file to discover all available pages before exploring further.
Overview
The WebSocket Real-Time Streaming API provides persistent, low-latency connections for real-time fleet monitoring, live vehicle tracking, instant event notifications, and continuous telemetry streaming. Perfect for building live dashboards, real-time alerts, and responsive fleet management applications.Authentication
WebSocket connections require authentication via query parameters or initial message:Query Parameter Authentication
wss://api.bookovia.com/v1/streaming/websocket?api_key=YOUR_API_KEY&fleet_id=fleet_001
Message-Based Authentication
{
"type": "auth",
"payload": {
"api_key": "YOUR_API_KEY",
"fleet_id": "fleet_001",
"subscriptions": ["vehicle_locations", "trip_events", "alerts"]
}
}
Connection Endpoints
Fleet Streaming
wss://api.bookovia.com/v1/streaming/websocket/fleet/{fleet_id}
Vehicle Streaming
wss://api.bookovia.com/v1/streaming/websocket/vehicle/{vehicle_id}
Trip Streaming
wss://api.bookovia.com/v1/streaming/websocket/trip/{trip_id}
Multi-Channel Streaming
wss://api.bookovia.com/v1/streaming/websocket
Subscription Types
| Type | Description | Update Frequency |
|---|---|---|
vehicle_locations | Real-time vehicle GPS positions | 1-30 seconds |
trip_events | Trip lifecycle events (start, stop, waypoint) | Event-driven |
alerts | Safety alerts and notifications | Immediate |
telemetry | Vehicle diagnostics and sensor data | 5-60 seconds |
fleet_metrics | Aggregated fleet performance metrics | 1-5 minutes |
driver_status | Driver availability and activity | Event-driven |
route_progress | Route execution and ETA updates | 30-60 seconds |
maintenance_alerts | Vehicle maintenance notifications | Event-driven |
Message Format
Outbound Messages (Client → Server)
{
"type": "message_type",
"id": "unique_message_id",
"timestamp": "2024-03-15T14:30:00Z",
"payload": {
"action": "subscribe|unsubscribe|request",
"data": {}
}
}
Inbound Messages (Server → Client)
{
"type": "message_type",
"id": "correlation_id",
"timestamp": "2024-03-15T14:30:00Z",
"channel": "subscription_channel",
"payload": {
"event": "event_name",
"data": {}
}
}
Real-Time Data Streams
Vehicle Location Updates
{
"type": "location_update",
"timestamp": "2024-03-15T14:30:00Z",
"channel": "vehicle_locations",
"payload": {
"vehicle_id": "vehicle_001",
"trip_id": "trip_12345",
"location": {
"latitude": 40.7128,
"longitude": -74.0060,
"accuracy": 5.2,
"altitude": 12.0,
"heading": 245.5,
"speed": 35.2
},
"telemetry": {
"fuel_level": 75.5,
"engine_rpm": 2100,
"odometer": 45678.2,
"engine_temp": 92.3
},
"driver_status": "driving",
"route_progress": {
"distance_completed": 15.3,
"distance_remaining": 8.7,
"eta": "2024-03-15T15:15:00Z",
"next_stop": "dest_003"
}
}
}
Trip Events
{
"type": "trip_event",
"timestamp": "2024-03-15T14:30:00Z",
"channel": "trip_events",
"payload": {
"event": "waypoint_reached",
"trip_id": "trip_12345",
"vehicle_id": "vehicle_001",
"driver_id": "driver_456",
"waypoint": {
"waypoint_id": "dest_002",
"location": {
"latitude": 40.7489,
"longitude": -73.9857,
"address": "123 Customer St, New York, NY"
},
"arrival_time": "2024-03-15T14:30:00Z",
"planned_time": "2024-03-15T14:25:00Z",
"delay_minutes": 5,
"activity_type": "delivery"
},
"route_update": {
"completed_stops": 2,
"remaining_stops": 6,
"updated_eta": "2024-03-15T17:45:00Z"
}
}
}
Safety Alerts
{
"type": "safety_alert",
"timestamp": "2024-03-15T14:30:00Z",
"channel": "alerts",
"payload": {
"alert_id": "alert_789",
"severity": "high",
"category": "harsh_braking",
"vehicle_id": "vehicle_001",
"driver_id": "driver_456",
"trip_id": "trip_12345",
"location": {
"latitude": 40.7128,
"longitude": -74.0060,
"address": "Broadway & 42nd St, New York, NY"
},
"event_data": {
"deceleration": -0.8,
"speed_before": 45.2,
"speed_after": 12.1,
"duration": 2.3
},
"recommended_actions": [
"Review driving behavior with driver",
"Check vehicle brake system",
"Monitor future driving patterns"
],
"auto_resolved": false
}
}
Fleet Metrics
{
"type": "fleet_metrics",
"timestamp": "2024-03-15T14:30:00Z",
"channel": "fleet_metrics",
"payload": {
"fleet_id": "fleet_001",
"metrics": {
"active_vehicles": 42,
"total_trips": 67,
"completed_deliveries": 89,
"average_speed": 28.5,
"fuel_efficiency": 12.3,
"on_time_percentage": 94.2,
"safety_score": 87.1
},
"alerts_summary": {
"critical": 0,
"high": 2,
"medium": 5,
"low": 12
},
"performance_trends": {
"utilization_trend": "+2.3%",
"efficiency_trend": "+1.8%",
"safety_trend": "-0.5%"
}
}
}
Client Implementation Examples
class BookoviaWebSocket {
constructor(apiKey, fleetId) {
this.apiKey = apiKey;
this.fleetId = fleetId;
this.ws = null;
this.reconnectAttempts = 0;
this.maxReconnectAttempts = 5;
this.subscriptions = new Set();
this.messageHandlers = new Map();
}
connect() {
const wsUrl = `wss://api.bookovia.com/v1/streaming/websocket?api_key=${this.apiKey}&fleet_id=${this.fleetId}`;
this.ws = new WebSocket(wsUrl);
this.ws.onopen = () => {
console.log('WebSocket connected');
this.reconnectAttempts = 0;
this.authenticate();
this.resubscribeAll();
};
this.ws.onmessage = (event) => {
try {
const message = JSON.parse(event.data);
this.handleMessage(message);
} catch (error) {
console.error('Failed to parse message:', error);
}
};
this.ws.onclose = (event) => {
console.log('WebSocket disconnected:', event.code, event.reason);
this.handleDisconnect();
};
this.ws.onerror = (error) => {
console.error('WebSocket error:', error);
};
}
authenticate() {
this.send({
type: 'auth',
payload: {
api_key: this.apiKey,
fleet_id: this.fleetId
}
});
}
subscribe(channel, handler) {
this.subscriptions.add(channel);
this.messageHandlers.set(channel, handler);
if (this.isConnected()) {
this.send({
type: 'subscribe',
payload: {
action: 'subscribe',
channel: channel
}
});
}
}
unsubscribe(channel) {
this.subscriptions.delete(channel);
this.messageHandlers.delete(channel);
if (this.isConnected()) {
this.send({
type: 'subscribe',
payload: {
action: 'unsubscribe',
channel: channel
}
});
}
}
send(message) {
if (this.isConnected()) {
message.id = this.generateMessageId();
message.timestamp = new Date().toISOString();
this.ws.send(JSON.stringify(message));
} else {
console.warn('WebSocket not connected, message queued');
}
}
handleMessage(message) {
const handler = this.messageHandlers.get(message.channel);
if (handler) {
handler(message.payload);
}
// Handle system messages
switch (message.type) {
case 'auth_success':
console.log('Authentication successful');
break;
case 'auth_error':
console.error('Authentication failed:', message.payload);
break;
case 'error':
console.error('Server error:', message.payload);
break;
}
}
handleDisconnect() {
if (this.reconnectAttempts < this.maxReconnectAttempts) {
const delay = Math.pow(2, this.reconnectAttempts) * 1000; // Exponential backoff
console.log(`Reconnecting in ${delay}ms...`);
setTimeout(() => {
this.reconnectAttempts++;
this.connect();
}, delay);
} else {
console.error('Max reconnection attempts reached');
}
}
resubscribeAll() {
for (const channel of this.subscriptions) {
this.send({
type: 'subscribe',
payload: {
action: 'subscribe',
channel: channel
}
});
}
}
isConnected() {
return this.ws && this.ws.readyState === WebSocket.OPEN;
}
generateMessageId() {
return Math.random().toString(36).substr(2, 9);
}
disconnect() {
if (this.ws) {
this.ws.close();
this.ws = null;
}
}
}
// Usage example
const wsClient = new BookoviaWebSocket('your-api-key', 'fleet_001');
// Connect
wsClient.connect();
// Subscribe to vehicle locations
wsClient.subscribe('vehicle_locations', (data) => {
console.log('Vehicle location update:', data);
updateVehicleOnMap(data.vehicle_id, data.location);
});
// Subscribe to trip events
wsClient.subscribe('trip_events', (data) => {
console.log('Trip event:', data);
updateTripStatus(data.trip_id, data.event);
});
// Subscribe to alerts
wsClient.subscribe('alerts', (data) => {
console.log('Alert received:', data);
if (data.severity === 'high' || data.severity === 'critical') {
showNotification(data);
}
});
// Subscribe to fleet metrics
wsClient.subscribe('fleet_metrics', (data) => {
console.log('Fleet metrics:', data);
updateDashboard(data.metrics);
});
function updateVehicleOnMap(vehicleId, location) {
// Update vehicle position on map
const marker = vehicleMarkers[vehicleId];
if (marker) {
marker.setPosition(new google.maps.LatLng(location.latitude, location.longitude));
}
}
function updateTripStatus(tripId, event) {
// Update trip status in UI
const tripElement = document.getElementById(`trip-${tripId}`);
if (tripElement) {
tripElement.textContent = `Status: ${event}`;
}
}
function showNotification(alert) {
// Show high-priority alert notification
new Notification(`${alert.category} Alert`, {
body: `Vehicle ${alert.vehicle_id}: ${alert.category}`,
icon: '/icons/alert.png'
});
}
function updateDashboard(metrics) {
// Update dashboard metrics
document.getElementById('active-vehicles').textContent = metrics.active_vehicles;
document.getElementById('on-time-rate').textContent = `${metrics.on_time_percentage}%`;
document.getElementById('safety-score').textContent = metrics.safety_score;
}
Use Cases
Real-Time Fleet Dashboard
Build live dashboards with real-time vehicle tracking and fleet metrics.class FleetDashboard {
constructor(apiKey, fleetId) {
this.wsClient = new BookoviaWebSocket(apiKey, fleetId);
this.vehicles = new Map();
this.metrics = {};
this.initializeSubscriptions();
this.setupUI();
}
initializeSubscriptions() {
// Vehicle tracking
this.wsClient.subscribe('vehicle_locations', (data) => {
this.updateVehiclePosition(data);
});
// Fleet metrics
this.wsClient.subscribe('fleet_metrics', (data) => {
this.updateFleetMetrics(data.metrics);
});
// Trip events
this.wsClient.subscribe('trip_events', (data) => {
this.handleTripEvent(data);
});
// Safety alerts
this.wsClient.subscribe('alerts', (data) => {
this.handleSafetyAlert(data);
});
}
updateVehiclePosition(data) {
const { vehicle_id, location, telemetry, route_progress } = data;
// Update vehicle marker on map
const marker = this.getVehicleMarker(vehicle_id);
marker.setPosition({
lat: location.latitude,
lng: location.longitude
});
// Update vehicle info panel
this.updateVehicleInfo(vehicle_id, {
location,
telemetry,
route_progress
});
// Store vehicle data
this.vehicles.set(vehicle_id, data);
}
updateFleetMetrics(metrics) {
this.metrics = metrics;
// Update dashboard widgets
document.getElementById('active-vehicles').textContent = metrics.active_vehicles;
document.getElementById('total-trips').textContent = metrics.total_trips;
document.getElementById('on-time-rate').textContent = `${metrics.on_time_percentage}%`;
document.getElementById('safety-score').textContent = metrics.safety_score;
// Update progress bars
this.updateProgressBar('utilization', metrics.active_vehicles / 50 * 100);
this.updateProgressBar('safety', metrics.safety_score);
}
handleTripEvent(data) {
const { event, trip_id, vehicle_id } = data;
// Update trip status in UI
const tripElement = document.querySelector(`[data-trip-id="${trip_id}"]`);
if (tripElement) {
tripElement.querySelector('.status').textContent = event;
tripElement.classList.add('updated');
setTimeout(() => {
tripElement.classList.remove('updated');
}, 2000);
}
// Show notification for important events
if (['trip_started', 'trip_completed', 'waypoint_reached'].includes(event)) {
this.showNotification(`${event.replace('_', ' ')}: Trip ${trip_id}`, 'info');
}
}
handleSafetyAlert(data) {
const { alert_id, severity, category, vehicle_id, location } = data;
// Add alert to alerts panel
this.addAlertToPanel(data);
// Show immediate notification for high-priority alerts
if (severity === 'high' || severity === 'critical') {
this.showNotification(
`${category} alert for vehicle ${vehicle_id}`,
'error'
);
// Flash vehicle marker
this.flashVehicleMarker(vehicle_id);
// Play alert sound
this.playAlertSound(severity);
}
}
}
Live Vehicle Tracking
Implement real-time vehicle tracking with route visualization.class LiveVehicleTracker:
def __init__(self, api_key: str, fleet_id: str):
self.ws_client = BookoviaWebSocketClient(api_key, fleet_id)
self.vehicle_positions = {}
self.route_traces = {}
async def start_tracking(self):
"""Start live vehicle tracking"""
await self.ws_client.subscribe('vehicle_locations', self.handle_location_update)
await self.ws_client.subscribe('trip_events', self.handle_trip_event)
await self.ws_client.connect()
async def handle_location_update(self, data):
"""Handle real-time location updates"""
vehicle_id = data['vehicle_id']
location = data['location']
# Update vehicle position
self.vehicle_positions[vehicle_id] = {
'latitude': location['latitude'],
'longitude': location['longitude'],
'heading': location['heading'],
'speed': location['speed'],
'timestamp': data.get('timestamp')
}
# Add point to route trace
if vehicle_id not in self.route_traces:
self.route_traces[vehicle_id] = []
self.route_traces[vehicle_id].append({
'lat': location['latitude'],
'lng': location['longitude'],
'timestamp': data.get('timestamp')
})
# Limit trace length (keep last 100 points)
if len(self.route_traces[vehicle_id]) > 100:
self.route_traces[vehicle_id] = self.route_traces[vehicle_id][-100:]
# Update route progress if available
if 'route_progress' in data:
await self.update_route_progress(vehicle_id, data['route_progress'])
# Emit update event
await self.emit_position_update(vehicle_id, data)
async def handle_trip_event(self, data):
"""Handle trip lifecycle events"""
trip_id = data['trip_id']
vehicle_id = data['vehicle_id']
event = data['event']
if event == 'trip_started':
# Initialize new route trace
self.route_traces[vehicle_id] = []
await self.emit_trip_started(trip_id, vehicle_id)
elif event == 'trip_completed':
# Save route trace
await self.save_route_trace(trip_id, vehicle_id)
await self.emit_trip_completed(trip_id, vehicle_id)
elif event == 'waypoint_reached':
waypoint = data.get('waypoint', {})
await self.emit_waypoint_reached(trip_id, vehicle_id, waypoint)
async def update_route_progress(self, vehicle_id: str, route_progress: dict):
"""Update route progress visualization"""
progress_data = {
'vehicle_id': vehicle_id,
'distance_completed': route_progress['distance_completed'],
'distance_remaining': route_progress['distance_remaining'],
'eta': route_progress['eta'],
'next_stop': route_progress['next_stop'],
'completion_percentage': (
route_progress['distance_completed'] /
(route_progress['distance_completed'] + route_progress['distance_remaining']) * 100
)
}
await self.emit_progress_update(progress_data)
async def get_vehicle_status(self, vehicle_id: str) -> dict:
"""Get current vehicle status"""
position = self.vehicle_positions.get(vehicle_id)
trace = self.route_traces.get(vehicle_id, [])
if not position:
return {'status': 'unknown', 'message': 'No recent location data'}
# Determine status based on movement and time
last_update = position.get('timestamp')
current_speed = position.get('speed', 0)
if current_speed > 5: # Moving
status = 'moving'
elif current_speed == 0: # Stopped
status = 'stopped'
else:
status = 'idle'
return {
'status': status,
'position': position,
'route_trace': trace,
'trace_length': len(trace)
}
async def emit_position_update(self, vehicle_id: str, data: dict):
"""Emit position update event (implement based on your event system)"""
# Implementation depends on your event system (WebSocket, message queue, etc.)
pass
async def emit_trip_started(self, trip_id: str, vehicle_id: str):
"""Emit trip started event"""
pass
async def emit_trip_completed(self, trip_id: str, vehicle_id: str):
"""Emit trip completed event"""
pass
async def emit_waypoint_reached(self, trip_id: str, vehicle_id: str, waypoint: dict):
"""Emit waypoint reached event"""
pass
async def emit_progress_update(self, progress_data: dict):
"""Emit route progress update event"""
pass
async def save_route_trace(self, trip_id: str, vehicle_id: str):
"""Save route trace to database"""
trace = self.route_traces.get(vehicle_id, [])
if trace:
# Save to database or file system
print(f"Saving route trace for trip {trip_id}: {len(trace)} points")
Alert Management System
Implement comprehensive alert handling with escalation and notification rules.type AlertManager struct {
wsClient *WebSocketClient
alertRules map[string]AlertRule
notificationSvc NotificationService
escalationSvc EscalationService
alertHistory []Alert
mutex sync.RWMutex
}
type AlertRule struct {
Severity string `json:"severity"`
Category string `json:"category"`
NotifyChannels []string `json:"notify_channels"`
EscalationDelay time.Duration `json:"escalation_delay"`
AutoResolve bool `json:"auto_resolve"`
Actions []string `json:"actions"`
}
type Alert struct {
ID string `json:"id"`
Timestamp time.Time `json:"timestamp"`
Severity string `json:"severity"`
Category string `json:"category"`
VehicleID string `json:"vehicle_id"`
DriverID string `json:"driver_id"`
Location map[string]interface{} `json:"location"`
Data map[string]interface{} `json:"data"`
Status string `json:"status"`
Acknowledged bool `json:"acknowledged"`
AcknowledgedBy string `json:"acknowledged_by"`
ResolvedAt *time.Time `json:"resolved_at"`
}
func NewAlertManager(wsClient *WebSocketClient) *AlertManager {
return &AlertManager{
wsClient: wsClient,
alertRules: make(map[string]AlertRule),
alertHistory: make([]Alert, 0),
}
}
func (am *AlertManager) Initialize() error {
// Load alert rules
am.loadAlertRules()
// Subscribe to alerts
return am.wsClient.Subscribe("alerts", am.handleAlert)
}
func (am *AlertManager) loadAlertRules() {
// Critical safety alerts
am.alertRules["harsh_braking"] = AlertRule{
Severity: "high",
Category: "safety",
NotifyChannels: []string{"sms", "email", "push"},
EscalationDelay: 5 * time.Minute,
AutoResolve: false,
Actions: []string{"driver_notification", "manager_alert"},
}
am.alertRules["collision_risk"] = AlertRule{
Severity: "critical",
Category: "safety",
NotifyChannels: []string{"sms", "email", "push", "phone_call"},
EscalationDelay: 2 * time.Minute,
AutoResolve: false,
Actions: []string{"emergency_contact", "dispatch_supervisor"},
}
am.alertRules["vehicle_breakdown"] = AlertRule{
Severity: "high",
Category: "maintenance",
NotifyChannels: []string{"email", "push"},
EscalationDelay: 10 * time.Minute,
AutoResolve: false,
Actions: []string{"maintenance_team", "roadside_assistance"},
}
am.alertRules["route_deviation"] = AlertRule{
Severity: "medium",
Category: "operational",
NotifyChannels: []string{"push"},
EscalationDelay: 15 * time.Minute,
AutoResolve: true,
Actions: []string{"route_optimization"},
}
}
func (am *AlertManager) handleAlert(payload map[string]interface{}) error {
alert := am.parseAlert(payload)
// Store alert
am.mutex.Lock()
am.alertHistory = append(am.alertHistory, alert)
am.mutex.Unlock()
// Apply alert rule
rule, exists := am.alertRules[alert.Category]
if !exists {
// Use default rule
rule = am.getDefaultRule(alert.Severity)
}
// Process alert
go am.processAlert(alert, rule)
return nil
}
func (am *AlertManager) processAlert(alert Alert, rule AlertRule) {
log.Printf("Processing alert: %s - %s - %s", alert.ID, alert.Category, alert.Severity)
// Send immediate notifications
for _, channel := range rule.NotifyChannels {
am.sendNotification(alert, channel)
}
// Execute automated actions
for _, action := range rule.Actions {
am.executeAction(alert, action)
}
// Set up escalation timer
if rule.EscalationDelay > 0 {
time.AfterFunc(rule.EscalationDelay, func() {
am.checkEscalation(alert.ID)
})
}
// Set up auto-resolution timer
if rule.AutoResolve {
time.AfterFunc(30*time.Minute, func() {
am.autoResolveAlert(alert.ID)
})
}
}
func (am *AlertManager) sendNotification(alert Alert, channel string) {
message := am.formatAlertMessage(alert)
switch channel {
case "sms":
am.notificationSvc.SendSMS(am.getContactsForAlert(alert), message)
case "email":
am.notificationSvc.SendEmail(am.getContactsForAlert(alert), "Fleet Alert", message)
case "push":
am.notificationSvc.SendPushNotification(message, alert.Severity)
case "phone_call":
am.notificationSvc.MakeEmergencyCall(am.getEmergencyContacts(alert), message)
}
}
func (am *AlertManager) executeAction(alert Alert, action string) {
switch action {
case "driver_notification":
am.sendDriverNotification(alert.DriverID, alert)
case "manager_alert":
am.alertManager(alert)
case "emergency_contact":
am.contactEmergencyServices(alert)
case "dispatch_supervisor":
am.dispatchSupervisor(alert)
case "maintenance_team":
am.alertMaintenanceTeam(alert)
case "roadside_assistance":
am.requestRoadsideAssistance(alert)
case "route_optimization":
am.triggerRouteOptimization(alert.VehicleID)
}
}
func (am *AlertManager) checkEscalation(alertID string) {
am.mutex.RLock()
var alert *Alert
for i := range am.alertHistory {
if am.alertHistory[i].ID == alertID {
alert = &am.alertHistory[i]
break
}
}
am.mutex.RUnlock()
if alert != nil && !alert.Acknowledged && alert.Status == "active" {
log.Printf("Escalating alert: %s", alertID)
am.escalateAlert(*alert)
}
}
func (am *AlertManager) escalateAlert(alert Alert) {
// Escalate to next level
supervisorContacts := am.getSupervisorContacts()
message := fmt.Sprintf("ESCALATED ALERT: %s - %s\nOriginal time: %s\nVehicle: %s",
alert.Category, alert.Severity, alert.Timestamp.Format(time.RFC3339), alert.VehicleID)
am.notificationSvc.SendEmail(supervisorContacts, "Escalated Fleet Alert", message)
am.notificationSvc.SendSMS(supervisorContacts, message)
}
func (am *AlertManager) AcknowledgeAlert(alertID, acknowledgedBy string) error {
am.mutex.Lock()
defer am.mutex.Unlock()
for i := range am.alertHistory {
if am.alertHistory[i].ID == alertID {
am.alertHistory[i].Acknowledged = true
am.alertHistory[i].AcknowledgedBy = acknowledgedBy
log.Printf("Alert %s acknowledged by %s", alertID, acknowledgedBy)
return nil
}
}
return fmt.Errorf("alert not found: %s", alertID)
}
func (am *AlertManager) ResolveAlert(alertID, resolvedBy string) error {
am.mutex.Lock()
defer am.mutex.Unlock()
for i := range am.alertHistory {
if am.alertHistory[i].ID == alertID {
now := time.Now()
am.alertHistory[i].Status = "resolved"
am.alertHistory[i].ResolvedAt = &now
log.Printf("Alert %s resolved by %s", alertID, resolvedBy)
return nil
}
}
return fmt.Errorf("alert not found: %s", alertID)
}
// Utility functions (implement based on your notification system)
func (am *AlertManager) parseAlert(payload map[string]interface{}) Alert {
// Parse WebSocket payload into Alert struct
return Alert{} // Implementation needed
}
func (am *AlertManager) formatAlertMessage(alert Alert) string {
return fmt.Sprintf("🚨 %s Alert: %s\nVehicle: %s\nTime: %s",
strings.ToUpper(alert.Severity), alert.Category, alert.VehicleID, alert.Timestamp.Format(time.RFC3339))
}
func (am *AlertManager) getContactsForAlert(alert Alert) []string {
// Return contact list based on alert and organizational structure
return []string{}
}
func (am *AlertManager) getEmergencyContacts(alert Alert) []string {
// Return emergency contact list
return []string{}
}
Best Practices
Connection Management
- Implement exponential backoff for reconnection attempts
- Handle authentication errors gracefully
- Monitor connection health with periodic heartbeats
- Use connection pooling for high-volume applications
Message Handling
- Implement message deduplication using message IDs
- Handle out-of-order messages appropriately
- Use structured error handling for malformed messages
- Implement message acknowledgment for critical events
Performance Optimization
- Subscribe only to necessary channels to reduce bandwidth
- Implement client-side message buffering for high-frequency updates
- Use compression for large message payloads
- Batch updates when possible to improve UI performance
Error Recovery
- Implement graceful degradation when WebSocket is unavailable
- Cache critical data locally for offline scenarios
- Provide fallback mechanisms (HTTP polling) when needed
- Log connection issues for troubleshooting
Related Endpoints
Explore other real-time capabilities:
- Telemetry Streaming API - Vehicle diagnostics
- Event Streaming API - Event notifications
- Trip Management API - Trip operations
- Safety Analytics API - Safety monitoring