How do you handle binary data over WebSockets?
Learn to send and receive binary data over WebSockets using ArrayBuffer, Blob, and DataView, plus schemas like Protobuf for compact, fast payloads.
Expected Interview Answer
WebSockets natively support binary frames, so you handle binary data by sending ArrayBuffer or Blob payloads and setting the socket's binaryType to control how incoming binary data is delivered.
A WebSocket connection carries either text (UTF-8) or binary frames, and the protocol tags each frame with an opcode so the receiver knows which it is. On the browser you set ws.binaryType to 'arraybuffer' (for random-access byte manipulation via typed arrays like Uint8Array/DataView) or 'blob' (for large opaque data you pass straight to file APIs). You send binary by passing an ArrayBuffer, TypedArray, or Blob to ws.send(). For structured payloads teams typically layer a schema like Protocol Buffers, MessagePack, or FlatBuffers on top, which is more compact and faster to parse than JSON text.
- Smaller payloads than base64-encoded text
- Zero-copy access to bytes via typed arrays and DataView
- Efficient for media, sensor streams, and game state
- Works with compact schemas like Protobuf or MessagePack
- Avoids the ~33% size overhead of encoding binary as text
AI Mentor Explanation
Sending binary over a WebSocket is like a fielding side using coded hand signals instead of shouting full sentences across the ground. A single gesture packs the field change, the bowler's plan, and the target end into one compact signal the whole team decodes instantly, saving breath and time compared to spelling every instruction out loud in slow, bulky words.
Step-by-Step Explanation
Step 1
Choose binaryType
Set ws.binaryType to 'arraybuffer' for byte-level access or 'blob' for large opaque data handed to file APIs.
Step 2
Encode the payload
Serialize your data into an ArrayBuffer, TypedArray, or Blob — often via Protobuf, MessagePack, or a manual DataView layout.
Step 3
Send the frame
Call ws.send(buffer); the protocol marks it as a binary frame automatically so the peer knows not to treat it as text.
Step 4
Receive and inspect
In onmessage, check event.data — for arraybuffer wrap it in a Uint8Array or DataView; for blob use arrayBuffer() or file APIs.
Step 5
Decode by schema
Read fields from known offsets or run the schema decoder to reconstruct the structured object on the receiving side.
What Interviewer Expects
- Awareness that WebSockets have distinct text and binary frame types
- Knowledge of binaryType 'arraybuffer' vs 'blob' and when to use each
- Ability to use ArrayBuffer, TypedArray, and DataView
- Reasons binary beats base64-in-text for size and speed
- Familiarity with schema formats like Protobuf or MessagePack
Common Mistakes
- Base64-encoding binary into text frames, adding ~33% overhead
- Forgetting to set binaryType, then treating a Blob as an ArrayBuffer
- Assuming JSON.parse works on incoming binary data
- Ignoring endianness when reading multi-byte numbers with DataView
- Not handling framing/length for messages split across reads on the server
Best Answer (HR Friendly)
“WebSockets can send raw binary data, not just text, so instead of converting things like images or game data into bulky text you send the actual bytes. You tell the socket what form incoming binary should arrive in, and the receiver reads those bytes directly, which is smaller and faster.”
Code Example
const ws = new WebSocket('wss://example.com/stream');
ws.binaryType = 'arraybuffer';
ws.onopen = () => {
const buf = new ArrayBuffer(8);
const view = new DataView(buf);
view.setUint32(0, 42); // id
view.setFloat32(4, 3.14); // value
ws.send(buf);
};
ws.onmessage = (event) => {
const view = new DataView(event.data);
const id = view.getUint32(0);
const value = view.getFloat32(4);
console.log(id, value);
};Follow-up Questions
- What is the difference between binaryType 'arraybuffer' and 'blob'?
- Why might you choose Protobuf or MessagePack over JSON on a WebSocket?
- How do you handle endianness when reading numbers from a DataView?
- How would you frame messages so the server can split a binary stream correctly?
- When is base64-over-text actually acceptable for binary payloads?
MCQ Practice
1. Which binaryType gives you random-access byte manipulation in the browser?
'arraybuffer' delivers data as an ArrayBuffer you can read with typed arrays or a DataView; 'blob' delivers an opaque Blob better suited to file APIs.
2. Why is sending raw binary usually better than base64-encoding it into a text frame?
Base64 encoding inflates payload size by about a third and adds encode/decode work, so native binary frames are smaller and faster.
3. What tool reads multi-byte numbers at specific offsets from an ArrayBuffer?
DataView lets you read/write typed values (Uint32, Float32, etc.) at chosen byte offsets, with explicit control over endianness.
Flash Cards
How does a WebSocket signal a binary vs text frame? — Each frame carries an opcode; text frames use UTF-8, binary frames carry raw bytes, so the receiver knows how to interpret the payload.
binaryType 'arraybuffer' vs 'blob' — 'arraybuffer' gives in-memory byte access via typed arrays/DataView; 'blob' gives an opaque object ideal for large data passed to file APIs.
Why avoid base64 over WebSockets? — It adds ~33% size overhead plus encode/decode cost; native binary frames are smaller and faster.
Common binary schemas on WebSockets — Protocol Buffers, MessagePack, and FlatBuffers — compact, schema-driven, faster to parse than JSON text.