하나씩 차근차근
article thumbnail

서버에 연결된 socket 을 join 메서드를 통해 room 에 연결을 해서 채팅방에 접속을 했습니다.

이번에는 클라이언트가 서버와 socket 을 통해 연결이 되면

서버에 저장된 채팅방의 목록을 가져와 브라우저에 그려주고

채팅방을 모달창을 통해 생성하도록 하겠습니다.

 

채팅방 목록 랜더링

먼저 home.html 파일을 다음과 같이 수정합니다.

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Chatting</title>
  </head>
  <body>
    <header>Chatting Web Page</header>
    <main>
      <h2>Welcome</h2>
      <div id="room">
        <ul id="roomList">
          <li>Room 1</li>
          <li>Room 2</li>
        </ul>
      </div>
      <form id="textSend">
        <input
          type="text"
          id="messageText"
          placeholder="메세지를 입력해주세요."
          ,
          required
        />
        <button type="submit">전송</button>
      </form>
    </main>
  </body>
  <script src="/socket.io/socket.io.js"></script>
  <script type="text/javascript" src="/js/app.js"></script>
</html>

서버에 저장된 채팅방 목록을 가져와서 javascript 를 통해 ul 태그 안에 넣어주겠습니다.

server.js 에 rooms 배열을 만들고 임시로 "room1", "room2" 를 넣어줍니다.

import express from "express";
import http from "http";
import SocketIO from "socket.io";

const app = express();
const httpServer = http.createServer(app);
const socketServer = SocketIO(httpServer);

const rooms = ["room1", "room2"];

app.use("/js", express.static(__dirname + "/js"));

app.get("/", (req, res) => res.sendFile(__dirname + "/views/" + "home.html"));
app.get("/*", (req, res) => res.redirect("/"));

socketServer.on("connection", (socket) => {
  sockets.push(socket);

  // 서버와 클라이언트가 연결되면 rooms 배열을 클라이언트로 보냄
  socket.emit("init", rooms);

  socket.on("send_message", (message) => console.log(message));

  socket.on("enter_room", (roomName) => {
    socket.join(roomName);
    console.log(socket.rooms);
  });
});

const handleListen = () => {
  console.log("Server Start");
};
httpServer.listen(3000, handleListen);

server.js 에서 socket 이 연결되면 클라이언트에 init 이벤트를 보냅니다.

init 이벤트를 통해 클라이언트는 rooms 배열에 저장된 채팅방 목록을 받게 됩니다.

const socket = io();

const form = document.getElementById("textSend");
const room = document.getElementById("room");
const roomList = document.getElementById("roomList");

// 서버와 연결됬을 경우 방 목록 그리기
socket.on("init", (rooms) => {
  rooms.forEach((room) => {
    const li = document.createElement("li");
    li.textContent = room;
    roomList.appendChild(li);
  });
});

function messageSubmit(event) {
  event.preventDefault();
  const input = document.getElementById("messageText");
  socket.emit("send_message", input.value);
  input.value = "";
}

function enterRoom(event) {
  socket.emit("enter_room", event.target.textContent);
}

form.addEventListener("submit", messageSubmit);
roomList.addEventListener("click", enterRoom);

클라이언트가 서버와 연결이 되면 기존의 Room1, Room2 밑에 서버에 저장된 room1, room2 가 랜더링 됩니다.

 

모달창을 통한 채팅방 생성

다음으로 모달창을 통해 채팅방을 생성해보겠습니다. 먼저 home.html 파일을 수정합니다.

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Chatting</title>
    <link rel="stylesheet" href="/style/home.css" />
  </head>
  <body>
    <header>Chatting Web Page</header>
    <main>
      <h2>Welcome</h2>
      <div id="room">
        <ul id="roomList">
          <li>Room 1</li>
          <li>Room 2</li>
        </ul>
        <button id="roomMake">방 만들기</button>
      </div>
      <div id="modal">
        <div id="modalContent">
          <input
            type="text"
            id="roomNameText"
            place="방 이름을 입력해주세요."
            ,required
          />
          <button id="roomMakeAndEnter">생성</button>
          <button id="cancel">취소</button>
        </div>
      </div>
      <form id="textSend">
        <input
          type="text"
          id="messageText"
          placeholder="메세지를 입력해주세요."
          ,
          required
        />
        <button type="submit">전송</button>
      </form>
    </main>
  </body>
  <script src="/socket.io/socket.io.js"></script>
  <script type="text/javascript" src="/js/app.js"></script>
</html>

다음으로 css 파일을 생성합니다.

#modal {
  position: fixed; /* Stay in place */
  z-index: 1; /* Sit on top */
  left: 0;
  top: 0;
  width: 100%; /* Full width */
  height: 100%; /* Full height */
  overflow: auto; /* Enable scroll if needed */
  background-color: rgba(0, 0, 0, 0.4); /* Black with opacity */
}

#modalContent {
  background-color: #fefefe;
  margin: 15% auto; /* 15% from the top and centered */
  padding: 20px;
  border: 1px solid #888;
  width: 80%; /* Could be more or less, depending on screen size */
}

생성한 css 파일을 서버에서 사용하기 위해서 server.js 에 css 파일이 있는 폴더를 등록해서

home.html 이 사용할 수 있도록 server.js 에 다음과 같이 설정을 추가합니다.

app.use("/js", express.static(__dirname + "/js"));
app.use("/style", express.static(__dirname + "/style"));

브라우저를 통해 localhost:3000/ 에 접속하면 <div id="room"> 을 통해 채팅방의 목록만 보이고

채팅방을 만드는 <div id="modal"> 과 메세지를 입력하는 <form id="textSend"> 은 hidden = true 상태입니다.

const socket = io();

const form = document.getElementById("textSend");
const room = document.getElementById("room");
const roomList = document.getElementById("roomList");
const roomMake = document.getElementById("roomMake");
const modal = document.getElementById("modal");

form.hidden = true;
modal.hidden = true;

// 서버와 연결됬을 경우 방 목록 그리기
socket.on("init", (rooms) => {
  rooms.forEach((room) => {
    const li = document.createElement("li");
    li.textContent = room;
    roomList.appendChild(li);
  });
});

function modalClick(event) {
  if (event.target.id == "modal") {
    // 모달창의 바깥부분을 클릭했을 경우 close
    modal.hidden = true;
  } else if (event.target.id == "roomMakeAndEnter") {
    // 생성 버튼을 클릭했을 경우
    const roomName = document.getElementById("roomNameText");
    socket.emit("make_room", roomName.value);

    const li = document.createElement("li");
    li.textContent = roomName.value;
    roomList.appendChild(li);

    // roomList와 modal의 hidden = true, message From의 hidden = false
    room.hidden = true;
    form.hidden = false;
    modal.hidden = true;
  } else if (event.target.id == "cancel") {
    // 취소버튼을 누르면 modal hidden = true
    modal.hidden = true;
  }
}

function messageSubmit(event) {
  event.preventDefault();
  const input = document.getElementById("messageText");
  socket.emit("send_message", input.value);
  input.value = "";
}

function enterRoom(event) {
  socket.emit("enter_room", event.target.textContent);
  room.hidden = true;
  form.hidden = false;
}

form.addEventListener("submit", messageSubmit);
roomList.addEventListener("click", enterRoom);

// 채팅방 생성 모달창 보여주기
roomMake.addEventListener("click", () => {
  modal.hidden = false;
});
modal.addEventListener("click", modalClick);

javascript 를 통해 "방 만들기" 버튼을 클릭하면 모달창이 나오면서

채팅방의 이름을 입력해서 서버로 보낼 수 있도록 작성했습니다.

profile

하나씩 차근차근

@jeehwan_lee

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!