Skip to content

[Feature] Create WebSocket Service for Real-Time Meter Reading and Stream Update Broadcasts #7

Description

@KarenZita01

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 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.

Technical Context & Impact

Step-by-Step Implementation Guide

  1. Install ws: Run npm install ws. No other external dependencies needed — ws handles the WebSocket protocol directly.
  2. 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.
  3. 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.
  4. 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().
  5. 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

  1. 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.
  2. Send a JSON message {"type": "subscribe", "channel": "meter:device1:readings"} — verify the server responds with a confirmation message.
  3. Programmatically call websocketService.broadcast("meter:device1:readings", { value: 123 }) and verify the connected client receives the message.
  4. Disconnect the client and verify the server cleans up subscriptions and reduces the active connection count.
  5. Wait for the heartbeat interval to expire without sending a pong — verify the connection is terminated and cleaned up.

Metadata

Metadata

Assignees

No one assigned

    Labels

    GrantFox OSSIssue tracked in GrantFox OSSMaybe RewardedIssue may be eligible for a GrantFox rewardOfficial Campaign | FWC26Campaign: Official Campaign | FWC26

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions