Skip to Content
Veltix
FeaturesReal-time Updates

Real-time Updates

Veltix provides powerful real-time update capabilities that enable your dashboards to display live data with minimal latency.

Overview

Real-time updates in Veltix support:

  • WebSocket Connections: Direct WebSocket communication
  • Polling Updates: Regular HTTP polling for data changes
  • Server-Sent Events: One-way real-time data streaming
  • Push Notifications: Instant data push to connected clients
  • Connection Management: Automatic reconnection and error handling

Update Modes

1. WebSocket Updates

Direct WebSocket connections for real-time bidirectional communication.

// WebSocket data source configuration const websocketDataSource = { type: 'websocket', url: 'ws://localhost:3001/realtime', protocols: ['realtime-protocol'], reconnect: true, reconnectInterval: 5000, maxReconnectAttempts: 10, onMessage: (data) => { console.log('Real-time data received:', data); }, onError: (error) => { console.error('WebSocket error:', error); } }; // Using WebSocket data source <BarChart dataSource={websocketDataSource} xField="timestamp" yField="value" realTime={true} />

2. Polling Updates

Regular HTTP polling for data that doesn’t require immediate updates.

// Polling data source configuration const pollingDataSource = { type: 'api', url: 'https://api.example.com/sales', refreshInterval: 30000, // 30 seconds refreshMode: 'polling', onUpdate: (data) => { console.log('Data updated via polling:', data); }, onError: (error) => { console.error('Polling error:', error); } }; // Using polling data source <LineChart dataSource={pollingDataSource} xField="date" yField="sales" realTime={true} />

3. Server-Sent Events

One-way real-time data streaming from server to client.

// SSE data source configuration const sseDataSource = { type: 'sse', url: 'https://api.example.com/events', eventTypes: ['data-update', 'status-change'], onMessage: (event) => { console.log('SSE event received:', event); }, onError: (error) => { console.error('SSE error:', error); } }; // Using SSE data source <PieChart dataSource={sseDataSource} nameField="category" valueField="amount" realTime={true} />

Connection Management

WebSocket Connection

import { useWebSocket } from '@veltix/pusher'; function RealTimeComponent() { const { connection, send, subscribe, unsubscribe, isConnected, reconnect } = useWebSocket({ url: 'ws://localhost:3001/realtime', options: { reconnect: true, reconnectInterval: 5000, maxReconnectAttempts: 10 } }); // Subscribe to data updates useEffect(() => { const unsubscribe = subscribe('sales-updates', (data) => { console.log('Sales data updated:', data); }); return () => unsubscribe(); }, [subscribe]); // Send message to server const sendUpdate = () => { send('request-update', { type: 'sales', period: 'daily' }); }; return ( <div> <div>Connection Status: {isConnected ? 'Connected' : 'Disconnected'}</div> <button onClick={sendUpdate}>Request Update</button> <button onClick={reconnect}>Reconnect</button> </div> ); }

Connection State Management

// Connection state hook const useConnectionState = () => { const [state, setState] = useState({ isConnected: false, isConnecting: false, isReconnecting: false, lastError: null, connectionCount: 0 }); const updateState = useCallback((updates) => { setState(prev => ({ ...prev, ...updates })); }, []); return { state, updateState }; }; // Connection monitoring const useConnectionMonitor = (connection) => { useEffect(() => { const handleConnect = () => { console.log('Connected to real-time service'); }; const handleDisconnect = () => { console.log('Disconnected from real-time service'); }; const handleError = (error) => { console.error('Connection error:', error); }; connection.on('connect', handleConnect); connection.on('disconnect', handleDisconnect); connection.on('error', handleError); return () => { connection.off('connect', handleConnect); connection.off('disconnect', handleDisconnect); connection.off('error', handleError); }; }, [connection]); };

Data Synchronization

Real-time Data Binding

// Real-time data binding const useRealTimeData = (dataSource) => { const [data, setData] = useState([]); const [loading, setLoading] = useState(false); const [error, setError] = useState(null); useEffect(() => { if (dataSource.type === 'websocket') { const connection = new WebSocket(dataSource.url); connection.onmessage = (event) => { const newData = JSON.parse(event.data); setData(newData); }; connection.onerror = (error) => { setError(error); }; return () => { connection.close(); }; } }, [dataSource]); return { data, loading, error }; }; // Using real-time data function RealTimeChart({ dataSource }) { const { data, loading, error } = useRealTimeData(dataSource); if (loading) return <div>Loading...</div>; if (error) return <div>Error: {error.message}</div>; return ( <BarChart data={data} xField="timestamp" yField="value" realTime={true} /> ); }

Data Transformation

// Real-time data transformation const useRealTimeTransform = (data, transforms) => { const transformedData = useMemo(() => { return transforms.reduce((acc, transform) => { switch (transform.type) { case 'filter': return acc.filter(item => item[transform.field] === transform.value ); case 'sort': return acc.sort((a, b) => a[transform.field] - b[transform.field] ); case 'aggregate': return aggregateData(acc, transform); default: return acc; } }, data); }, [data, transforms]); return transformedData; }; // Using transformed real-time data function TransformedRealTimeChart({ data, transforms }) { const transformedData = useRealTimeTransform(data, transforms); return ( <LineChart data={transformedData} xField="timestamp" yField="value" realTime={true} /> ); }

Performance Optimization

Efficient Updates

// Optimized real-time updates const useOptimizedRealTime = (dataSource, options = {}) => { const { throttle = 100, // Throttle updates to 100ms batchUpdates = true, // Batch multiple updates maxDataPoints = 1000 // Limit data points for performance } = options; const [data, setData] = useState([]); const updateQueue = useRef([]); const lastUpdate = useRef(0); const processUpdate = useCallback((newData) => { const now = Date.now(); if (batchUpdates) { updateQueue.current.push(newData); if (now - lastUpdate.current > throttle) { const batchedData = updateQueue.current; updateQueue.current = []; lastUpdate.current = now; setData(prevData => { const updatedData = [...prevData, ...batchedData]; // Limit data points for performance return updatedData.slice(-maxDataPoints); }); } } else { setData(prevData => { const updatedData = [...prevData, newData]; return updatedData.slice(-maxDataPoints); }); } }, [throttle, batchUpdates, maxDataPoints]); return { data, processUpdate }; };

Memory Management

// Memory-efficient real-time data const useMemoryOptimizedRealTime = (maxPoints = 1000) => { const [data, setData] = useState([]); const dataRef = useRef([]); const addDataPoint = useCallback((newPoint) => { dataRef.current = [...dataRef.current, newPoint]; // Keep only the latest data points if (dataRef.current.length > maxPoints) { dataRef.current = dataRef.current.slice(-maxPoints); } setData([...dataRef.current]); }, [maxPoints]); const clearData = useCallback(() => { dataRef.current = []; setData([]); }, []); return { data, addDataPoint, clearData }; };

Error Handling

Connection Error Handling

// Robust error handling for real-time connections const useRealTimeErrorHandling = (connection) => { const [error, setError] = useState(null); const [retryCount, setRetryCount] = useState(0); const maxRetries = 5; const handleError = useCallback((error) => { console.error('Real-time connection error:', error); setError(error); if (retryCount < maxRetries) { setTimeout(() => { setRetryCount(prev => prev + 1); connection.reconnect(); }, Math.pow(2, retryCount) * 1000); // Exponential backoff } }, [connection, retryCount, maxRetries]); const resetError = useCallback(() => { setError(null); setRetryCount(0); }, []); useEffect(() => { connection.on('error', handleError); connection.on('connect', resetError); return () => { connection.off('error', handleError); connection.off('connect', resetError); }; }, [connection, handleError, resetError]); return { error, retryCount, resetError }; };

Data Validation

// Real-time data validation const validateRealTimeData = (data, schema) => { try { // Validate data structure if (!Array.isArray(data)) { throw new Error('Data must be an array'); } // Validate each data point const validatedData = data.map((item, index) => { const { error } = schema.validate(item); if (error) { throw new Error(`Invalid data at index ${index}: ${error.message}`); } return item; }); return { valid: true, data: validatedData }; } catch (error) { return { valid: false, error: error.message }; } }; // Using data validation const useValidatedRealTimeData = (dataSource, schema) => { const [data, setData] = useState([]); const [validationError, setValidationError] = useState(null); useEffect(() => { const handleData = (rawData) => { const validation = validateRealTimeData(rawData, schema); if (validation.valid) { setData(validation.data); setValidationError(null); } else { setValidationError(validation.error); console.error('Data validation failed:', validation.error); } }; // Subscribe to data updates dataSource.on('data', handleData); return () => { dataSource.off('data', handleData); }; }, [dataSource, schema]); return { data, validationError }; };

Configuration Examples

WebSocket Configuration

// Advanced WebSocket configuration const advancedWebSocketConfig = { url: 'wss://api.example.com/realtime', protocols: ['realtime-v1'], options: { reconnect: true, reconnectInterval: 5000, maxReconnectAttempts: 10, heartbeat: 30000, timeout: 10000, compression: true }, authentication: { type: 'jwt', token: 'your-jwt-token' }, subscriptions: [ 'sales-updates', 'inventory-changes', 'user-activity' ] };

Polling Configuration

// Advanced polling configuration const advancedPollingConfig = { url: 'https://api.example.com/data', interval: 30000, // 30 seconds options: { retryAttempts: 3, retryDelay: 1000, timeout: 5000, headers: { 'Authorization': 'Bearer your-token' } }, dataTransformation: (data) => { return data.map(item => ({ ...item, timestamp: new Date(item.timestamp), value: parseFloat(item.value) })); }, errorHandling: { onError: (error) => { console.error('Polling error:', error); // Implement fallback strategy }, fallbackData: [] } };

Best Practices

1. Connection Management

  • Implement automatic reconnection
  • Use exponential backoff for retries
  • Monitor connection health
  • Handle connection errors gracefully

2. Data Handling

  • Validate incoming data
  • Implement data transformation
  • Limit data points for performance
  • Use efficient data structures

3. Performance

  • Throttle frequent updates
  • Batch multiple updates
  • Implement memory management
  • Monitor resource usage

4. Error Handling

  • Implement comprehensive error handling
  • Provide fallback mechanisms
  • Log errors for debugging
  • Graceful degradation

5. Security

  • Use secure WebSocket connections (WSS)
  • Implement proper authentication
  • Validate all incoming data
  • Monitor for suspicious activity

Troubleshooting

Common Issues

Connection not establishing

  • Check WebSocket URL and protocol
  • Verify server is running
  • Check firewall settings
  • Test with simple WebSocket client

Data not updating

  • Verify subscription to correct channels
  • Check data format and structure
  • Monitor connection status
  • Review error logs

Performance issues

  • Reduce update frequency
  • Implement data throttling
  • Limit data points
  • Use efficient data structures

Memory leaks

  • Clean up event listeners
  • Limit data storage
  • Implement proper cleanup
  • Monitor memory usage
Last updated on