Skip to content

feat(ws): WebSocket channel for real-time stream updates (#49)#111

Merged
Jagadeeshftw merged 2 commits intoFluxora-Org:mainfrom
JosephOnuh:feature/websocket-stream-updates
Mar 31, 2026
Merged

feat(ws): WebSocket channel for real-time stream updates (#49)#111
Jagadeeshftw merged 2 commits intoFluxora-Org:mainfrom
JosephOnuh:feature/websocket-stream-updates

Conversation

@JosephOnuh
Copy link
Copy Markdown
Contributor

Summary

Closes #49

Implements the WebSocket channel for real-time stream updates described in issue #49.
Clients can connect to ws://<host>/ws/streams and receive live events whenever a
stream is created, updated, or cancelled.

Changes

New: src/websockets/streamChannel.ts

  • Attaches a ws.Server to the existing HTTP server (no extra port)
  • Exports broadcast(), getConnectionCount(), closeWebSocketServer()
  • Per-connection rate limiting: 10 messages / 10 s → close with code 1008
  • Max client message size: 4 KiB → close with code 1009
  • Heartbeat ping/pong every 30 s prunes unresponsive connections
  • Structured JSON logs on connect/disconnect with connectionId and total

Modified: src/services/streamEventService.ts

  • Calls broadcast() after each successful StreamCreated, StreamUpdated, and StreamCancelled mutation — single source of truth from the indexer

Modified: src/routes/health.ts

  • GET /health now includes wsConnections (live client count)

Modified: src/index.ts

  • Attaches WebSocket server after app.listen()
  • Registers closeWebSocketServer via addShutdownHook for graceful shutdown

New: tests/websocket.test.ts

8 integration tests covering:

  • Broadcast delivers to a single connected client
  • Broadcast delivers to multiple clients simultaneously
  • No-op when no clients are connected
  • Oversized client message → connection closed with code 1009
  • Rate limit exceeded → connection closed with code 1008
  • Connection count tracked accurately across connect/disconnect
  • service.degraded event delivered to clients
  • Abrupt client disconnect does not throw on next broadcast

Modified: README.md

  • Added WebSocket API section with message schema, abuse prevention table, operator observability notes, manual verification steps (wscat), and explicit non-goals with follow-up tracking

Non-goals (documented, not deferred silently)

  • Authentication / authorization on the WS endpoint — follow-up: JWT or API-key on upgrade
  • Message replay / durable event log — events are fire-and-forget
  • Per-stream subscription filtering — all clients receive all events

Verification

bash

Run new tests

npx vitest run tests/websocket.test.ts

Manual smoke test

npm run dev
wscat -c ws://localhost:3000/ws/streams

In another terminal, create a stream via POST /api/streams and watch the event arrive

Health check includes wsConnections

curl http://localhost:3000/health | jq .wsConnec

JosephOnuh and others added 2 commits March 30, 2026 11:56
)

- Add src/websockets/streamChannel.ts: ws.Server attached to existing
  HTTP server at /ws/streams; broadcast(), getConnectionCount(),
  closeWebSocketServer() exported for use by routes and shutdown
- Enforce per-connection rate limit (10 msg / 10 s → close 1008)
- Enforce max client message size (4 KiB → close 1009)
- Heartbeat ping/pong every 30 s prunes dead connections
- Emit stream.created / stream.updated / stream.cancelled events from
  streamEventService after each successful mutation
- GET /health now includes wsConnections count
- Register WS teardown via addShutdownHook for graceful shutdown
- Add tests/websocket.test.ts: 8 integration tests covering broadcast,
  multi-client delivery, oversized payload, rate limit, connection
  count tracking, degraded event, and abrupt disconnect
- README: add WebSocket API section with schema, abuse limits,
  observability notes, manual verification steps, and non-goals
@Jagadeeshftw Jagadeeshftw merged commit 9ba0ee2 into Fluxora-Org:main Mar 31, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Websocket channel for stream updates (optional)

2 participants