ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [포스코x코딩온] Socket.IO를 활용한 채팅 만들기(1)
    [포스코x코딩온] 웹개발자 풀스택 부트캠프8기 2023. 8. 29. 21:53
    728x90

    Socket.IO를 활용한 채팅 만들기(1)

    룸(Room)기능을 활용하여 여러명의 채팅을 할 수 있게 하고 자신의 메시지는 오른쪽에 다른 사람의 메시지는 왼쪽에 뜨게 하기

    실행 결과

     


    매커니즘

    1. 프롬프트를 통해 룸(Room)과 이름을 설정
    2. 프롬프트에서 설정한 룸(Room)을 가지고 Socket.IO 룸(Room) 설정
    3. 클라이언트에서 데이터 보낼 때 이름과 메시지 보내기
    4. 서버에서 모든 사용자에게 데이터를 보내는 io함수 사용
    5. 클라이언트에서 데이터 받을 때 자신의 이름과 받아온 이름을 비교하여 왼쪽 및 오른쪽 정렬하기

    프롬프트를 통해 룸(Room)과 이름을 설정

    프롬프트에서 설정한 룸(Room)을 가지고 Socket.IO 룸(Room) 설정

    • 클라이언트
      • 프롬프트를 통해 받아온 chatroom 데이터를 서버로 보낸다.
    const chatroom = prompt("채팅방을 입력하세요. ");
          const Username = prompt("이름을 입력하세요. ");
          socket.emit("join", chatroom);
    • 서버
      • 받은 chatroom을 가지고 join을 한다.
    io.on("connection", (socket) => {
      console.log("id", socket.id);
      console.log("조인전", socket.rooms);
      socket.on("join", (chatroom) => {
        socket.join(chatroom);
        socket.room = chatroom; //socket은 객체 형태라서 socket.room에 지정.
        console.log("조인후", socket.rooms);
      });

    두개의 클라이언트로 같은 룸에 접속한 결과


     

    클라이언트에서 데이터 보낼때 이름과 메시지 보내기

    <body>
        <div id="space"></div>
        <form id="chat">
          <input type="text" id="message" placeholder="채팅내용" />
          <button>채팅</button>
        </form>
        <script>
              chatForm.addEventListener("submit", (e) => {
            e.preventDefault();
            const msg = chatForm.querySelector("#message");
            socket.emit("message", { name: Username, msg: msg.value });
            msg.value = "";
          });
        </script>
      </body>

     

    • 폼 전송으로 데이터를 보낸다.

    서버에서 모든 사용자에게 데이터를 보내는 io함수 사용

    socket.on("message", (message) => {
        console.log(message);
        //io.to(특정방).emit(이벤트): 특정방의 전체 사용자에게 메시지 전달
        io.to(socket.room).emit("send", message);
      });

    클라이언트에서 데이터 받을 때 자신의 이름과 받아온 이름을 비교하여 왼쪽 및 오른쪽 정렬하기

    <!DOCTYPE html>
    <html lang="en">
        <style>
          #space {
            width: 30vh;
            height: 50vh;
            background-color: yellow;
            flex-direction: column;
          }
    
          .right-align {
            text-align: right;
          }
    
          .left-align {
            text-align: left;
          }
        </style>
      <body>
        <div id="space"></div>
        <script>
          const space = document.querySelector("#space");
    
          socket.on("send", (message) => {
            if (message.name === Username) {
              const p = document.createElement("p");
              p.textContent = `${message.name}: ${message.msg}`;
              p.classList.add("right-align"); // 오른쪽 정렬 클래스 추가
              space.appendChild(p);
            } else {
              const p = document.createElement("p");
              p.textContent = `${message.name}: ${message.msg}`;
              p.classList.add("left-align"); // 왼쪽 정렬 클래스 추가
              space.appendChild(p);
            }
          });
        </script>
      </body>
    </html>
    • 조건문을 사용하여 왼쪽이랑 오른쪽 정렬을 한다.

    전체 코드

    • 클라이언트
    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <script src="/socket.io/socket.io.js"></script>
    
        <title>Document</title>
        <style>
          #space {
            width: 30vh;
            height: 50vh;
            background-color: yellow;
            flex-direction: column;
          }
    
          .right-align {
            text-align: right;
          }
    
          .left-align {
            text-align: left;
          }
        </style>
      </head>
      <body>
        <div id="space"></div>
        <form id="chat">
          <input type="text" id="message" placeholder="채팅내용" />
          <button>채팅</button>
        </form>
        <script>
          const chatForm = document.querySelector("#chat");
          const space = document.querySelector("#space");
          const socket = io();
          const chatroom = prompt("채팅방을 입력하세요. ");
          const Username = prompt("이름을 입력하세요. ");
          socket.emit("join", chatroom);
    
          socket.on("userjoin", (message) => {
            console.log(message);
          });
          socket.on("send", (message) => {
            if (message.name === Username) {
              const p = document.createElement("p");
              p.textContent = `${message.name}: ${message.msg}`;
              p.classList.add("right-align"); // 오른쪽 정렬 클래스 추가
              space.appendChild(p);
            } else {
              const p = document.createElement("p");
              p.textContent = `${message.name}: ${message.msg}`;
              p.classList.add("left-align"); // 왼쪽 정렬 클래스 추가
              space.appendChild(p);
            }
          });
    
          chatForm.addEventListener("submit", (e) => {
            e.preventDefault();
            const msg = chatForm.querySelector("#message");
            socket.emit("message", { name: Username, msg: msg.value });
            msg.value = "";
          });
        </script>
      </body>
    </html>

    • 서버
    const http = require("http");
    const express = require("express");
    const SocketIO = require("socket.io");
    
    const app = express();
    const PORT = 8000;
    
    //http서버
    const server = http.createServer(app);
    //socket서버
    const io = SocketIO(server);
    
    app.set("view engine", "ejs");
    
    app.get("/", (req, res) => {
      res.render("client");
    });
    
    app.get("/chat", (req, res) => {
      res.render("chat");
    });
    
    //==========소켓=========//
    //받아오는 갯수가 같아야 한다.
    io.on("connection", (socket) => {
      console.log("id", socket.id);
      console.log("조인전", socket.rooms);
      socket.on("join", (chatroom) => {
        socket.join(chatroom);
        socket.room = chatroom; //socket은 객체 형태라서 socket.room에 지정.
        console.log("조인후", socket.rooms);
        socket.broadcast.to(chatroom).emit("userjoin", `사용자가 입장하셨습니다.`);
      });
      socket.on("message", (message) => {
        console.log(message);
        //io.to(특정방).emit(이벤트): 특정방의 전체 사용자에게 메시지 전달
        io.to(socket.room).emit("send", message);
      });
    });
    
    //서버오픈
    server.listen(PORT, () => {
      console.log(`http://localhost:${PORT}`);
    });

    일단 채팅방 UI와 내가 보낸 메시지와 상대방이 보낸 메시지에 대한 정렬 구분 기능을 구현

     

    다음글에서는 채팅방에 입장할 때 안내 문구가 나오는 기능을 구현하겠습니다.

    728x90
Designed by Tistory.