Length-Prefixed Binary Protocol
Hard · Networking
TCP gives you a stream of bytes, not messages: one data event can contain half a message or three messages glued together. A common fix is length-prefix framing: every message starts with its length. In Node you would write the prefix with buf.writeUInt32BE(length); here you use DataView, which does the same on an ArrayBuffer.
Frame format (numbers are big-endian):
- 4 bytes: length = the number of bytes that follow (1 type byte + the payload bytes)
- 1 byte: type, an integer from 0 to 255
- length - 1 bytes: the payload, a UTF-8 string
Implement:
- encodeMessage({ type, payload }) returns the frame as an array of numbers. If type is not an integer from 0 to 255, throw an error with the message "invalid type".
- class MessageDecoder with constructor(maxLength) and push(bytes). bytes is an array of numbers that can be cut at any point. push returns an array of the messages { type, payload } that became complete (often []).
- Safety: as soon as the 4 length bytes are known, if length > maxLength add { error: "message too large" } to the result without waiting for the body, and if length === 0 add { error: "empty frame" }. After an error the decoder is broken and every later push returns [].
Use TextEncoder / TextDecoder for UTF-8. A character like é takes 2 bytes, so count bytes, not characters. The driver runProtocol(maxLength, ops) is already written: ["encode", type, payload] outputs the encoded array (or "error: <message>"), and ["push", bytes] outputs what push returned.
Next: LRU Cache With TTL