JAVASCRIPT
Real-time API Communication with WebSockets
Establish persistent, full-duplex communication channels with a backend API using WebSockets for instant, event-driven data exchange in web applications.
/**
* Sets up a WebSocket connection for real-time API communication.
* @param {string} wsUrl - The WebSocket endpoint URL (e.g., 'ws://localhost:8080/ws' or 'wss://example.com/ws').
* @param {object} handlers - An object containing event handler functions.
* @param {function(): void} [handlers.onOpen] - Called when the WebSocket connection opens.
* @param {function(event: MessageEvent): void} [handlers.onMessage] - Called when a message is received.
* @param {function(event: CloseEvent): void} [handlers.onClose] - Called when the WebSocket connection closes.
* @param {function(event: Event): void} [handlers.onError] - Called when a WebSocket error occurs.
* @returns {{ send: (message: string | object) => void, close: () => void, getConnection: () => WebSocket }} An object with methods to interact with the WebSocket.
*/
function setupWebSocket(wsUrl, handlers = {}) {
let ws;
let reconnectAttempts = 0;
const MAX_RECONNECT_ATTEMPTS = 5;
const RECONNECT_DELAY = 2000; // milliseconds
const connect = () => {
ws = new WebSocket(wsUrl);
ws.onopen = (event) => {
console.log('WebSocket connection opened:', event);
reconnectAttempts = 0; // Reset attempts on successful connection
if (handlers.onOpen) handlers.onOpen();
};
ws.onmessage = (event) => {
console.log('WebSocket message received:', event.data);
if (handlers.onMessage) handlers.onMessage(event);
};
ws.onclose = (event) => {
console.warn('WebSocket connection closed:', event);
if (handlers.onClose) handlers.onClose(event);
// Attempt to reconnect if the closure was not intentional
if (!event.wasClean && reconnectAttempts < MAX_RECONNECT_ATTEMPTS) {
reconnectAttempts++;
console.log(`Attempting to reconnect WebSocket (attempt ${reconnectAttempts}/${MAX_RECONNECT_ATTEMPTS})...`);
setTimeout(connect, RECONNECT_DELAY * Math.pow(2, reconnectAttempts - 1)); // Exponential backoff for reconnect
}
};
ws.onerror = (event) => {
console.error('WebSocket error:', event);
if (handlers.onError) handlers.onError(event);
// Error might lead to close, which then triggers reconnect logic
};
};
const send = (message) => {
if (ws && ws.readyState === WebSocket.OPEN) {
const dataToSend = typeof message === 'object' ? JSON.stringify(message) : message;
ws.send(dataToSend);
} else {
console.warn('WebSocket is not open. Message not sent:', message);
}
};
const close = () => {
if (ws) {
ws.close(1000, 'Client initiated close'); // 1000 is Normal Closure
}
};
// Initial connection
connect();
return {
send,
close,
getConnection: () => ws // For direct access if needed, though discouraged
};
}
// Example usage:
// const myWebSocket = setupWebSocket('wss://echo.websocket.events', {
// onOpen: () => {
// console.log('Connected to WebSocket server!');
// myWebSocket.send('Hello from client!');
// myWebSocket.send({ type: 'SUBSCRIBE', channel: 'updates' });
// },
// onMessage: (event) => {
// try {
// const data = JSON.parse(event.data);
// console.log('Parsed message:', data);
// // Update UI based on data
// document.getElementById('websocket-messages').innerHTML += `<p>${JSON.stringify(data)}</p>`;
// } catch (e) {
// console.log('Raw message:', event.data);
// document.getElementById('websocket-messages').innerHTML += `<p>${event.data}</p>`;
// }
// },
// onClose: (event) => {
// console.log('WebSocket disconnected:', event.reason);
// },
// onError: (event) => {
// console.error('WebSocket encountered an error:', event);
// }
// });
// // Send messages manually
// // setTimeout(() => myWebSocket.send('Another message after 5 seconds.'), 5000);
// // Close the connection after a while
// // setTimeout(() => myWebSocket.close(), 15000);
How it works: This snippet demonstrates how to establish and manage a WebSocket connection for real-time, bidirectional communication with an API. The `setupWebSocket` function handles connection creation, defines event listeners for `open`, `message`, `close`, and `error` events, and includes basic reconnection logic with exponential backoff for resilience. WebSockets offer a more efficient alternative to traditional HTTP polling for applications requiring instant data updates, such as chat applications, live dashboards, or gaming.