You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The EquipChain platform needs real-time communication capabilities to push meter reading updates, contract events, and system notifications to connected clients without requiring constant polling. This issue implements a WebSocket service built on the ws library that integrates with the existing HTTP server (Express 5.x) and provides a publish/subscribe mechanism for broadcasting stream updates.
The WebSocket server should be attached to the same HTTP server as Express to share ports and simplify deployment. Clients will connect to /ws and can subscribe to specific channels such as meter:{deviceId}:readings, contract:{contractId}:events, and system:alerts. The subscription model must support both public channels (anyone can listen) and authenticated channels (require valid JWT from Issue #5). The WebSocket service should handle connection lifecycle events: open, message, close, and error, with proper cleanup of subscriptions on disconnect.
Heartbeat functionality using ping/pong frames should be implemented to detect stale connections and clean them up after a configurable timeout (default 30 seconds). The service should emit metrics (active connections, messages per second, channel distribution) for monitoring purposes (Issue #16). Broadcasting to all subscribers of a channel must be efficient using a Map-based channel registry.
Architecture: New src/services/websocket.js managing the WebSocket server and channel subscriptions. New src/middleware/wsAuth.js for authenticating WebSocket connections via JWT. Integration point in src/index.js to attach the WebSocket server to the existing HTTP server.
Install ws: Run npm install ws. No other external dependencies needed — ws handles the WebSocket protocol directly.
Create WebSocket Service: Write src/services/websocket.js. Export a class WebSocketService that accepts an HTTP server instance. Implement setup() to create ws.Server, handle connection events, track connections in a Map. Implement methods: subscribe(ws, channel), unsubscribe(ws, channel), broadcast(channel, message), closeConnection(ws). Implement heartbeat interval checking for stale connections.
Create WebSocket Auth Middleware: Write src/middleware/wsAuth.js that parses the sec-websocket-protocol header or a query parameter for a JWT token, validates it using the auth service (Issue [Testing] Expand Test Coverage with Integration Tests, API Tests, and Mock Blockchain Layer #5), and attaches user info to the WebSocket object. This middleware is used during the upgrade event before the connection is established.
Integrate with Express App: Modify src/index.js to create the WebSocket server attached to the Express HTTP server. Expose the WebSocketService instance so other services (contract listener, admin alerts) can call broadcast().
Write Tests: Create tests/unit/websocket.test.js testing connection, subscription, broadcasting, and heartbeat timeout logic using a mock WebSocket server. Create tests/integration/websocket.test.js testing the full WebSocket lifecycle via supertest with WebSocket client.
Verification & Testing Steps
Start the server and use wscat (or a similar WebSocket client) to connect to ws://localhost:3000/ws — verify the connection is accepted and a welcome message is received.
Send a JSON message {"type": "subscribe", "channel": "meter:device1:readings"} — verify the server responds with a confirmation message.
Programmatically call websocketService.broadcast("meter:device1:readings", { value: 123 }) and verify the connected client receives the message.
Disconnect the client and verify the server cleans up subscriptions and reduces the active connection count.
Wait for the heartbeat interval to expire without sending a pong — verify the connection is terminated and cleaned up.
Description
The EquipChain platform needs real-time communication capabilities to push meter reading updates, contract events, and system notifications to connected clients without requiring constant polling. This issue implements a WebSocket service built on the
wslibrary that integrates with the existing HTTP server (Express 5.x) and provides a publish/subscribe mechanism for broadcasting stream updates.The WebSocket server should be attached to the same HTTP server as Express to share ports and simplify deployment. Clients will connect to
/wsand can subscribe to specific channels such asmeter:{deviceId}:readings,contract:{contractId}:events, andsystem:alerts. The subscription model must support both public channels (anyone can listen) and authenticated channels (require valid JWT from Issue #5). The WebSocket service should handle connection lifecycle events: open, message, close, and error, with proper cleanup of subscriptions on disconnect.Heartbeat functionality using ping/pong frames should be implemented to detect stale connections and clean them up after a configurable timeout (default 30 seconds). The service should emit metrics (active connections, messages per second, channel distribution) for monitoring purposes (Issue #16). Broadcasting to all subscribers of a channel must be efficient using a Map-based channel registry.
Technical Context & Impact
ws(WebSocket library),uuid(already installed from Issue [Middleware] Add Request Logging, Error Handling, Rate Limiting, and Request Validation Middleware #6) for connection IDs. No additional infrastructure required — the WebSocket server runs in-process.src/services/websocket.jsmanaging the WebSocket server and channel subscriptions. Newsrc/middleware/wsAuth.jsfor authenticating WebSocket connections via JWT. Integration point insrc/index.jsto attach the WebSocket server to the existing HTTP server.Step-by-Step Implementation Guide
npm install ws. No other external dependencies needed —wshandles the WebSocket protocol directly.src/services/websocket.js. Export a classWebSocketServicethat accepts an HTTP server instance. Implementsetup()to createws.Server, handleconnectionevents, track connections in a Map. Implement methods:subscribe(ws, channel),unsubscribe(ws, channel),broadcast(channel, message),closeConnection(ws). Implement heartbeat interval checking for stale connections.src/middleware/wsAuth.jsthat parses thesec-websocket-protocolheader or a query parameter for a JWT token, validates it using the auth service (Issue [Testing] Expand Test Coverage with Integration Tests, API Tests, and Mock Blockchain Layer #5), and attaches user info to the WebSocket object. This middleware is used during theupgradeevent before the connection is established.src/index.jsto create the WebSocket server attached to the Express HTTP server. Expose the WebSocketService instance so other services (contract listener, admin alerts) can callbroadcast().tests/unit/websocket.test.jstesting connection, subscription, broadcasting, and heartbeat timeout logic using a mock WebSocket server. Createtests/integration/websocket.test.jstesting the full WebSocket lifecycle via supertest with WebSocket client.Verification & Testing Steps
wscat(or a similar WebSocket client) to connect tows://localhost:3000/ws— verify the connection is accepted and a welcome message is received.{"type": "subscribe", "channel": "meter:device1:readings"}— verify the server responds with a confirmation message.websocketService.broadcast("meter:device1:readings", { value: 123 })and verify the connected client receives the message.