C.W.K.
Stream
Lesson 07 of 07 · published

Message 순서, Size & ACK

~13 min · protocol, ordering, ack, asyncapi

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

WebSocket 이 in-order 보장

단일 connection 안에서 WebSocket frame 이 send 순서대로 도착 — TCP 보장이 위로 흐름. reordering 없고 protocol-level dedup 없음. 재연결하면 그 보장 reset: 새 connection 은 독립.

Frame size 한계

Protocol 이 이론상 거대한 frame (2^63 byte) 허용, 근데 모든 구현이 cap. production default 보통 64KB-1MB. 더 큰 payload 는 명시적 chunking: metadata 있는 file.start, binary chunk stream, file.end. 한 logical message = 한 frame 가정 금지.

Application-level ACK

Message 가 반드시 전달되어야 (chat message, payment confirm) 하면 application layer 에 acknowledgement: 클라가 sequence number 와 보내고, 서버가 그 number 와 ack 응답, 클라가 ack 안 오면 retransmit. WebSocket 자체와 독립 — 재연결 살아남아.

AsyncAPI 로 문서화

AsyncAPI 가 event-driven, message-based API 의 OpenAPI. channel, operation, message schema 를 YAML 에 정의; doc, mock, 클라 코드 generate. 협소한 type 몇 개 넘으면 가치 있어.

Code

WebSocket 위 chunked file upload·javascript
async function uploadFile(ws, file) {
  const CHUNK = 64 * 1024;
  const total = Math.ceil(file.size / CHUNK);
  ws.send(JSON.stringify({
    type: 'file.start',
    data: { name: file.name, size: file.size, chunks: total },
  }));
  for (let i = 0; i < total; i++) {
    const slice = file.slice(i * CHUNK, (i + 1) * CHUNK);
    const buf = await slice.arrayBuffer();
    ws.send(buf);
  }
  ws.send(JSON.stringify({ type: 'file.end' }));
}
Application-level ACK + retry·javascript
const unacked = new Map();
let nextSeq = 0;

function sendReliable(ws, type, data) {
  const seq = ++nextSeq;
  const msg = { seq, type, data };
  unacked.set(seq, { msg, attempts: 1 });
  ws.send(JSON.stringify(msg));
  setTimeout(() => retryIfStillUnacked(ws, seq), 5_000);
}

function retryIfStillUnacked(ws, seq) {
  const entry = unacked.get(seq);
  if (!entry) return;
  if (entry.attempts >= 3) {
    unacked.delete(seq);
    notifyUserOfFailure(seq);
    return;
  }
  entry.attempts += 1;
  ws.send(JSON.stringify(entry.msg));
  setTimeout(() => retryIfStillUnacked(ws, seq), 5_000);
}

ws.onmessage = (e) => {
  const m = JSON.parse(e.data);
  if (m.type === 'ack') unacked.delete(m.seq);
};

External links

Exercise

WebSocket 위 chunked file upload 짜. 5MB 파일 골라 64KB chunk 로 분할. 서버가 reassemble 후 디스크 저장. size 일치 확인. mid-upload 에 connection drop — 서버에 partial file 있는 거 봐. file.resume message 추가해서 다음 chunk 인덱스부터 재개 가능하게.

Progress

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

댓글 0

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

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