C.W.K.
Stream
Lesson 06 of 08 · published

Binary Data

~11 min · browser, binary, dataview

Level 0Poller
0 XP0/60 lessons0/10 achievements
0/120 XP to next level120 XP to go0% complete

Binary 가 왜 필요한가

JSON 은 사람이 읽기 쉽고, 디버깅 쉽고, 느려. 고빈도 또는 compact message — multiplayer 게임 position, market tick, sensor stream — 엔 JSON tax 가 bandwidth 비용과 dropped frame 으로 나타나. binary 로 payload size 60-80% 자르고 parse time 은 더 짤려. 브라우저가 binary 네이티브 지원, 비용은 encoder/decoder 직접 짜는 거.

DataView 가 친구

DataViewArrayBuffer 의 byte offset 에서 typed value 읽고 써. endianness 명시적으로 픽 (거의 항상 little-endian 으로 true 넘겨), 같은 wire format 이 JS 클라와 Python 서버 사이 작동하게. 알려진 offset 으로 여러 field 를 한 buffer 에 합치면 hand-rolled binary protocol 완성.

MessagePack 또는 Protobuf 골라야 할 때

Hand-rolled binary 는 field 적은 tightly-defined message 엔 ok. protocol 자라면 — schema evolution, optional field, nested structure — MessagePack (drop-in JSON 대체, 30% 작아, schema 없음) 또는 Protobuf (best compression, .proto 정의 필요) 손 가. Track 5 에서 다뤄.

Code

Player position pack & unpack·javascript
ws.binaryType = 'arraybuffer';

// Encode: id(uint16) + x(int16) + y(int16) + flags(uint8)
function encodePos(id, x, y, flags) {
  const buf = new ArrayBuffer(7);
  const v = new DataView(buf);
  v.setUint16(0, id, true);
  v.setInt16(2, x, true);
  v.setInt16(4, y, true);
  v.setUint8(6, flags);
  return buf;
}

ws.send(encodePos(42, 150, -300, 0b0001));

ws.addEventListener('message', (e) => {
  if (!(e.data instanceof ArrayBuffer)) return;
  const v = new DataView(e.data);
  const id = v.getUint16(0, true);
  const x  = v.getInt16(2, true);
  const y  = v.getInt16(4, true);
  const flags = v.getUint8(6);
  applyPosition(id, x, y, flags);
});
한 frame 에 여러 position stream·javascript
// 7 bytes per record, N records in one frame
function encodeAll(positions) {
  const buf = new ArrayBuffer(positions.length * 7);
  const v = new DataView(buf);
  positions.forEach((p, i) => {
    const o = i * 7;
    v.setUint16(o,     p.id, true);
    v.setInt16( o + 2, p.x,  true);
    v.setInt16( o + 4, p.y,  true);
    v.setUint8( o + 6, p.flags);
  });
  return buf;
}

External links

Exercise

같은 player-position protocol 을 JSON 과 binary 로 profile. {id, x, y, flags} update 1,000 개를 JSON 으로 보낸 후, 위 7-byte binary 로 또 보내. 측정: (a) wire 위 총 byte 수 (network 탭), (b) 1,000 개 parse 시간 (performance.now() 으로 JSON.parse vs DataView 읽기 둘러싸). 비율 적어.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.