프로그래밍 언어/NODE JS

실시간 GIF 채팅방 만들기(3)

· 코딩마이데이

채팅방 생성 화면을 담당하는 room.html 파일을 작성합니다.

{% extends 'layout.html' %} {% block content %}
<fieldset>
  <legend>채팅방 생성</legend>
  <form action="/room" method="post">
    <div>
      <input type="text" name="title" placeholder="방 제목" />
    </div>
    <div>
      <input
        type="number"
        name="max"
        placeholder="수용 인원(최소 2명)"
        min="2"
        value="10"
      />
    </div>
    <div>
      <input
        type="password"
        name="password"
        placeholder="비밀번호(없으면 공개방)"
      />
    </div>
    <div>
      <button type="submit">생성</button>
    </div>
  </form>
</fieldset>
{% endblock %}

 

채팅방 화면을 담당하는 chat.html 파일을 작성합니다.

{% extends 'layout.html' %} {% block content %}
<h1>{{title}}</h1>
<a href="/" id="exit-btn">방 나가기</a>
<fieldset>
  <legend>채팅 내용</legend>
  <div id="chat-list">
    {% for chat in chats %} {% if chat.user === user %}
    <div class="mine" style="color: {{chat.user}}">
      <div>{{chat.user}}</div>
      {% if chat.gif %}
      <img src="/gif/{{chat.gif}}" />
      {% else %}
      <div>{{chat.chat}}</div>
      {% endif %}
    </div>
    {% elif chat.user === 'system' %}
    <div class="system">
      <div>{{chat.chat}}</div>
    </div>
    {% else %}
    <div class="other" style="colo: {{chat.user}}">
      <div>{{chat.user}}</div>
      {% if chat.gif %}
      <img src="/gif/{{chat.gif}}" />
      {% else %}
      <div>{{chat.chat}}</div>
      {% endif %}
    </div>
    {% endif %} {% endfor %}
  </div>
</fieldset>
<form action="/chat" id="chat-form" method="post" enctype="multipart/form-data">
  <label for="gif">GIF 올리기</label>
  <input type="file" id="gif" name="gif" accept="image/gif" />
  <input type="text" id="chat" name="chat" />
  <button type="submit">전송</button>
</form>
<script>
  const socket = io.connect("http://localhost:8005/chat", {
    path: "/socket.io",
  });
  socket.on("join", function (data) {
    const div = document.createElement("div");
    div.classList.add("system");
    const chat = document.createElement("div");
    div.textContent = data.chat;
    div.appendChild(chat);
    document.querySelector("#chat-list").appendChild(div);
  });
  socket.on("exit", function (data) {
    const div = document.createElement("div");
    div.classList.add("system");
    const chat = document.createElement("div");
    div.textContent = data.chat;
    div.appendChild(chat);
    document.querySelector("#chat-list").appendChild(div);
  });
</script>
{% endblock %}

 

채팅 메시지 세 가지, 즉 내 메시지(mine), 시스템 메시지(system), 남의 메시지(other)로 구분했습니다. 메시지 종류에 따라 메시지 지 디자인(main.css를 참고하세요)이 달라집니다.

스크립트 부분이 복잡하지만 크게 socket.io 연결 부분, socket.io 이벤트 리스너, 폼 전송 부분으로 구분됩니다.

socket.io 연결 부분을 살펴보면 io.connect 메서드의 주소가 main.html과는 다릅니다. 이번에는 네임스페이스가 /chat입니다. /room 네임스페이스로 보낸 데이터는 받을 수 없고, /chat 네임스페이스로 보낸 데이터만 받을 수 있습니다.

socket에는 join, exit 이벤트 리스너를 연결했습니다. join과 exit은 각각 사용자의 입장과 퇴장에 관한 데이터가 웹 소켓으로 전송될 때 호출됩니다. 사용자의 입장과 퇴장을 알리는 메시지를 표시합니다.