stelar-time-real is designed around a single principle: total control over the network layer. Rather than wrapping a third-party WebSocket library, it implements RFC 6455 from scratch using Node.jsDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/foxytp/stelar-time-real/llms.txt
Use this file to discover all available pages before exploring further.
http, crypto, and zlib, and pairs it with a purpose-built binary TCP protocol implemented over net (and optionally tls). Both transports are first-class citizens — they share the same event handlers, rooms, broadcast system, ACK system, middleware stack, and metrics.
Dual Protocol
The server starts two listeners: an HTTP server that handles WebSocket upgrades, and a raw TCP server (or TLS TCP server) for the binary protocol. Clients choose which transport to use based on their environment and requirements.Both protocols share everything at the application layer: event handlers registered with
.on(), room membership and fan-out via .to(), broadcasts via .broadcast(), the ACK request-response system, the middleware chain registered with .use(), and all server metrics returned by .getStats(). A WebSocket client and a TCP client can be in the same room and exchange messages without any special handling.WebSocket vs TCP
| Aspect | WebSocket | Custom TCP |
|---|---|---|
| Browser support | ✅ Yes | ❌ No |
| Node.js support | ✅ Yes | ✅ Yes |
| Overhead per frame | 2–14 bytes (RFC 6455 header) | 7 bytes (custom header) |
| Latency | Low | Ultra-low |
| TLS | wss:// via HTTP upgrade | Native TLS socket (tls.connect) |
| Typical use case | Frontend web apps, browsers | Microservices, backend-to-backend |
Binary Protocol Format (TCP)
The custom TCP protocol uses a compact 7-byte fixed header followed by a variable-length event name and payload. There is no null-delimiter — lengths are encoded explicitly in big-endian integers so the parser always knows exactly how many bytes to read.totalLen(4 bytes, BE) — Total frame length in bytes, including the header itself.type(1 byte) — Frame type identifier (see table below).eventLen(2 bytes, BE) — Length of the UTF-8 event name string that follows.event(N bytes) — UTF-8 event name.payload(remaining bytes) — JSON-encoded data or raw binary, depending on frame type.
Frame Types
All 11 frame type codes are defined as sequential hex values starting at0x01 in src/protocol.ts:
| Code | Hex | Name | Description |
|---|---|---|---|
1 | 0x01 | JSON | Event with a JSON-encoded payload |
2 | 0x02 | Binary | Event with a raw binary payload (no JSON encoding) |
3 | 0x03 | Ping | Client heartbeat request |
4 | 0x04 | Pong | Server heartbeat response |
5 | 0x05 | ACK Request | Request that expects a response from the server |
6 | 0x06 | ACK Response | Server’s response to an ACK Request |
7 | 0x07 | Connect | Initial connection frame (server sends assigned client ID) |
8 | 0x08 | Disconnect | Graceful disconnection frame |
9 | 0x09 | Join Room | Client requests to join a named room |
10 | 0x0A | Leave Room | Client requests to leave a named room |
11 | 0x0B | Error | Error frame from server to client |
WebSocket Implementation (RFC 6455)
stelar-time-real implements the full WebSocket handshake and framing layer using only Node.jshttp, crypto, and zlib. The ws npm package is never used.
The implementation covers:
- Handshake — Computes
Sec-WebSocket-Acceptusing SHA-1 and base64 per RFC 6455 §4 - Framing — Full frame parsing and construction for text, binary, ping, pong, and close opcodes
- Masking — Applies and removes the XOR mask required on client-to-server frames (RFC 6455 §5.3)
- Fragmentation — Correctly assembles fragmented multi-frame messages
- Close codes — All standard close codes supported (
1000,1001,1002,1003,1007,1008,1009,1011, etc.) - RSV bit validation — Frames with unexpected RSV2/RSV3 bits set are rejected with a protocol error close
- PING / PONG — Server responds to client PING frames with a PONG containing the same payload
- permessage-deflate — Optional per-message compression (RFC 7692) using Node.js
zlib; negotiated during the handshake viaSec-WebSocket-Extensions
No external
ws package is used at any point. All WebSocket framing logic lives in src/websocket.ts and relies exclusively on Node.js built-in modules. This means no third-party CVEs can affect the WebSocket layer.Project Structure
index.tsowns the server lifecycle, connection management, rate limiting, health endpoint, graceful shutdown, and the dispatch loop that routes frames to registered event handlers.client.tshandles all three connection paths (browserWebSocketAPI, Node.js WebSocket viahttp.requestupgrade, and raw TCP vianet.createConnection), plus reconnection with exponential backoff, message queuing, and the ACK Promise system.protocol.tsandwebsocket.tsare pure encoding/decoding modules with no I/O — they can be tested and reasoned about in complete isolation from the networking layer.
