Summary

  • W3C가 2009년 4월 23일 공개한 Server-Sent Events 작업 초안은 페이지가 EventSource로 서버의 연속적인 소식을 받는 방식을 설명했다.
  • 이벤트에는 id를 붙일 수 있다. 연결이 끊긴 뒤 브라우저는 기억한 ID를 Last-Event-ID로 다시 보내며, 값이 없는 id는 그 기억을 지운다.

시세판 숫자가 멈춘다. 시장이 잠깐 다 함께 숨을 고른다면 좋겠지만, 대개는 선이 끊긴 것이다. 잠시 뒤 숫자가 다시 바뀌면 안심하기보다 한 번 더 봐야 한다. 이전 숫자와 지금 숫자 사이에 몇 건이 지나갔는지 화면은 저절로 말해 주지 않는다. 실시간이라는 말이 가장 난처해지는 순간이다.

W3C가 2009년 4월 23일 낸 작업 초안은 EventSource를 제시했다. 페이지가 URL을 열고 소식을 기다리면 서버는 text/event-stream 형식의 HTTP 응답으로 계속 보낸다. 브라우저는 들어오는 줄을 읽어 한 묶음이 끝날 때마다 페이지에 이벤트를 전달한다. 긴 연결 하나를 유지하면서도 각각의 소식에 경계를 줄 수 있었다. 끊어진 뒤 어디서 다시 말을 잇는지도 이 설계의 일부였다.

초안의 주식 예시는 요란하지 않다. data: YHOO, data: +2, data: 10 세 줄이 오고 빈 줄이 뒤따른다. 브라우저는 세 줄을 한 이벤트로 묶어 넘긴다. 페이지의 처리 함수는 값을 갈라 시세를 갱신한다. 빈 줄은 계속 이어지는 종이 띠 위에 찍힌 마침표다. 연결은 열려 있어도 한 소식이 어디서 끝나는지는 분명하다.

다음 예시에는 책갈피가 등장한다. data: first event와 함께 id: 1이 온다. 브라우저는 1을 기억한다. 다음 사건이 도착하기 전에 선이 끊기면 새 요청에 Last-Event-ID: 1을 싣는다. 2009년 12월의 최종 의견 수렴 초안에도 이 재접속 방식이 남았다. 접수 창구에 돌아온 독자가 “어디까지 읽었는지 모르겠어요”라고 말하는 대신, 마지막으로 읽은 쪽을 펼쳐 보이는 셈이다.

그 책갈피가 완성된 다음 장을 품고 있는 것은 아니다. 서버가 과거 이벤트를 보관했다면 받은 ID를 기준으로 이어질 항목을 고를 수 있다. 기록을 정리했거나 거래일이 바뀌었다면 다른 결정을 내려야 한다. 보관 기간과 재전송 정책은 소식을 가진 쪽의 일이다. 브라우저는 자신이 실제로 받은 지점을 알고, 서버는 자신이 다시 꺼낼 수 있는 목록을 안다. ID는 두 사람이 같은 위치를 가리키게 해 준다.

초안은 책갈피를 지우는 방법도 보여 줬다. 뒤이은 이벤트에 값이 없는 id 필드가 있으면 기억한 ID가 비워진다. 다음에 다시 연결할 때 Last-Event-ID 헤더가 사라진다. 어제의 장 마감 번호가 오늘 아침 첫 기사에 따라붙지 않게 하는 장치다. 계속 읽으라는 신호만큼, 새 책을 펼치라는 신호도 중요했다.

콜론으로 시작하는 줄은 주석이다. 브라우저가 읽지만 페이지에 새 이벤트를 띄우지 않는다. 2015년 2월 W3C 권고안은 조용한 연결을 일부 오래된 프록시가 끊어 버리는 경우, 이런 주석을 가끔 보내는 방안을 설명했다. 재시도 대기 시간을 조절하는 retry도 정리했고, HTTP 204 No Content로 더는 재접속하지 말라고 알리는 방법도 명시했다. 속보를 전하는 기계에는 “아직 여기 있다”는 헛기침과 “오늘은 여기까지”라는 퇴근 인사가 모두 필요하다.

W3C의 발행 이력을 보면 2009년 작업 초안, 2012년 후보 권고안 스냅샷, 2015년 권고안이 차례로 놓인다. 여러 해를 거치며 남은 핵심은 소박하다. 데이터를 몇 줄로 보내고, 사건에 번호를 붙이고, 연결이 돌아올 때 마지막 번호를 건넨다. 거창한 기억력이 아니라 정확한 질문 하나를 만드는 기술이었다. “나는 여기까지 들었다. 다음은 무엇인가?”

최근 다룬 Web Workers와도 역할이 다르다. Worker는 페이지의 클릭을 막지 않도록 오래 걸리는 계산을 다른 실행 공간으로 보낸다. EventSource는 서버에서 오는 소식의 흐름을 받아들이고, 끊긴 뒤 마지막 수신 위치를 돌려준다. 한쪽은 누가 일을 할지를 나누고, 다른 쪽은 누가 순서를 기억할지를 나눈다. 시세 띠에는 두 번째 문제가 꽤 절실했다.