항해14기 본과정/항해14기 개발일지

[항해 14기] 개발일지36 (클론프로젝트)

스쿼트잘함 2023. 5. 13. 23:04

클론프로젝트 주차

 

1. 작업 내역

- BE 아키택쳐/스트럭쳐/ERD 설계

- FE-BE 연결

- 댓글 CRUD

- like 로직

- 채팅 구현

 

 

 

2. socket.io로 채팅 구현

*DB 필요한 로직 생략

1) 클라이언트 로직

더보기
const socket = io();

socket.on("connect", () => {
  let name = prompt("닉네임을 적어주세요", "") || "익명";
  let room = prompt("방번호를 적어주세요", "") || "기본방";

  socket.emit("newUser", name, room);
});

socket.on("update", (data) => {
  console.log(`${data.name}:${data.message}`);
  let chat = document.getElementById("chat");
  let message = document.createElement("span");
  let node = document.createTextNode(`${data.name}: ${data.message}`);
  let className = "";

  switch (data.type) {
    case "message":
      className = "other";
      break;

    case "connect":
      className = "connect";
      break;

    case "disconnect":
      className = "disconnect";
      break;
  }

  message.classList.add(className);
  message.appendChild(node);
  chat.appendChild(message);
});

function handleKeyDown(event) {
  if (event.keyCode === 13) {
    event.preventDefault();
    send();
  }
}

function send() {
  let message = document.getElementById("test").value;
  document.getElementById("test").value = "";

  let chat = document.getElementById("chat");
  let msg = document.createElement("span");
  let node = document.createTextNode(message);

  msg.classList.add("me");
  msg.appendChild(node);
  chat.appendChild(msg);

  socket.emit("message", { type: "message", message: message, read: false });
}

 

2) html/css

더보기
<!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>채팅 페이지</title>

    <link rel="stylesheet" href="/css/main.css" />
    <script src="/socket.io/socket.io.js"></script>
    <script src="/js/main.js"></script>
  </head>
  <body>
    <div id="main">
      <div id="chat"></div>
      <div id="chat2">
        <input
          type="text"
          id="test"
          placeholder="메시지를 입력해주세요"
          onkeydown="handleKeyDown(event)" />
        <button type="button" class="button" onclick="send()">전송</button>
      </div>
    </div>
  </body>
</html>
/* 메인 */
#main {
    margin: auto;
    margin-top: 100px;
    border-radius: 20px;
    background-color: rgb(207, 182, 162);
    text-align: center;
    width: 480px;
    height: 800px;
    border: 5px solid rgb(187, 146, 146);
    position: relative;
  }
  
  #chat {   
    width: 100%;
    height: 740px;
    overflow-y: scroll;   
    padding-bottom: 10px;
  }

  #chat::-webkit-scrollbar {
    display: none;
  }

  /* 채팅 영역 */
  #chat2 {
    position: absolute;
    bottom: 20px;
    margin-top: 50px;    
    width: 100%;
    overflow-y: auto;
  }
  
  /* 접속 알림 */
  .connect {
    width: 100%;
    margin: 10px auto;
    text-align: center;
    display: inline-block;
  }
  
  /* 접속 종료 알림 */
  .disconnect {
    width: 90%;
    margin: auto;
    text-align: center;
    margin-top: 10px;
  }
  
  /* 내가 보낸 메시지 */
  .me {
    display: block;
    max-width: 280px;
    padding: 5px;      
    margin: auto;
    background-color: rgb(202, 142, 107);
    border-radius: 5px;
    text-align : right;
    margin-top: 10px;
    margin-right: 15px;    
  }
  
  /* 상대방이 보낸 메시지 */
  .other {
    display: block;
    max-width: 280px; 
    padding: 5px; 
    margin: auto;
    background-color: rgb(189, 189, 189);
    border-radius: 5px;
    text-align : left;
    margin-top: 10px;
    margin-left: 15px;    
  }

 

3) 서버 로직

더보기
const express = require("express");
const app = express();
const socket = require("socket.io");
const http = require("http");
const chatServer = http.createServer(app);
const io = socket(chatServer);
const chatPort = 3001;

// parser
app.use(express.urlencoded({ extended: false }));
app.use(express.json());

// chat
app.use("/css", express.static("./static/css"));
app.use("/js", express.static("./static/js"));

io.on("connection", (socket) => {
  socket.on("newUser", (name, room) => {
    console.log(`${name}님이 ${room}에 접속하셨습니다.`);
    socket.name = name;
    socket.room = room;
    socket.join(room);

    io.to(socket.room).emit("update", {
      type: "connect",
      name: "POTATO MASTER",
      message: `${name}님이 ${room}방에 접속하셨습니다.`,
    });
  });

  socket.on("message", (data) => {
    data.id = socket.id;
    data.name = socket.name;
    data.room = socket.room;
    console.log("서버2", data);
    socket.broadcast.to(socket.room).emit("update", data);
  });

  socket.on("disconnect", () => {
    console.log(`${socket.name} 님이 나가셨습니다.`);
    io.to(socket.room).emit("update", {
      type: "disconnect",
      name: "POTATO MASTER",
      message: `${socket.name} 님이 나가셨습니다.`,
    });
  }); 
});

chatServer.listen(chatPort, () => {
  console.log(`running http://localhost:${chatPort}`);
});

module.exports = app;
const PostsService = require("../services/posts.service");
const fs = require("fs");

class ChatController {
  postsService = new PostsService();

  chat = async (req, res) => {
   
    fs.readFile("./static/index.html", (err, data) => {
      if (err) {
        res.send("오류났음");
      } else {
        res.writeHead(200, { "Content-Type": "text/html" });
        res.write(data);
        res.end();
      }
    });
  };
}

module.exports = ChatController;

 

4) 화면