프로그래밍 언어/NODE JS

실시간 경매 시스템 - 서버센트 이벤트 사용하기(2)

· 코딩마이데이

서버센트 이벤트는 한 가지 단점이 있습니다. IE나 엣지 브라우저에서 사용할 수 없다는 것입니다. EventSource라는 객체를 지원하지 않기 때문인데, 다행히 EventSource를 사용자가 직접 구현할 수 있습니다. IE나 엣지 브라우저를 위해 클라이언트 코드에 EventSource 폴리필(polyfill)을 넣었습니다.

 

views/main.html

{% extends 'layout.html' %} {% block content %}
<div class="timeline">
  <h2>경매 진행 목록</h2>
  <table id="good-list">
    <tr>
      <th>상품명</th>
      <th>이미지</th>
      <th>시작 가격</th>
      <th>종료 시간</th>
      <th>입장</th>
    </tr>
    {% for good in goods %}
    <tr>
      <td>{{good.name}}</td>
      <td>
        <img src="/img/{{good.img}}" />
      </td>
      <td>{{good.price}}</td>
      <td class="time" data-start="{{good.createdAt}}">00:00:00</td>
      <td>
        <a href="/good/{{good.id}}" class="enter btn">입장</a>
      </td>
    </tr>
    {% endfor %}
  </table>
</div>
{% endblock %}

<script src="https://unpkg.com/event-source-polyfill/src/eventsource.min.js"></script>
<script>
  const es = new EventSource("sse");
  es.onmessage = function (e) {
    document.querySelectorAll("time").forEach((td) => {
      const end = new Date(td.dataset.start); // 경매 시작 시간
      const server = new Date(parseInt(e.data, 10));
      end.setDate(end.getDate() + 1); // 경매 종료 시간
      if (server >= end) {
        // 경매가 종료되었으면
        return (td.textContent = "00:00:00");
      } else {
        const t = end - server; // 경매 종료까지 남은 시간
        const seconds = ("0" + Math.floor((t / 1000) % 60)).slice(-2);
        const minutes = ("0" + Math.floor((t / 1000 / 60) % 60)).slice(-2);
        const hours = ("0" + Math.floor((t / (1000 * 60 * 60)) % 24)).slice(-2);
        return (td.textContent = hours + ":" + minutes + ":" + seconds);
      }
    });
  };
</script>

 

첫 번째 스크립트가 EventSource 폴리필입니다. 이것을 넣으면 IE와 엣지 브라우저에서도 서버센트 이벤트를 사용할 수 있습니다. 두 번째 스크립트는 EventSource를 사용해 서버센트 이벤트를 받은 코드입니다. new EventSource('/sse')로 서버와 연결하고, es.onmessage 또는 es.addEventListener('message') 이벤트 리스너로부터 데이터를 받을 수 있습니다. 서버로부터 받은 데이터는 e.data에 들어 있습니다. 아랫부분은 서버 시간과 경매 종료 시간을 계산해 카운트다운하는 코드입니다. 24시간 동안 카운트다운하는 코드입니다. 24시간 동안 카운트다운되도록 했습니다.

 

개발자 도구의 Network 탭을 확인합니다.

Network 탭

 

eventsource.min.js는 조금 전에 추가한 EventSource 폴리필 파일입니다. GET /see가 바로 서버센트 이벤트를 접속한 것입니다. Type이 eventsource로 나와 있습니다. 일반 HTTP 연결을 통해 서버센트 이벤트를 사용할 수 있습니다.

GET /sse를 클릭해보면 EventStream 탭이 있는데, 여기서 매 초마다 서버로부터 타임스탬프 데이터가 오는 것을 확인할 수 있습니다.