본문 바로가기

코딩/NodeJS

nodejs로 채팅방 기능 만들기

반응형

1. 개요

  • 게시글 간의 종속관계를 알아야 함
  • 채팅기능 = 댓글기능 + 실시간 통신임
    • 채팅방에 접속 후 메시지 전송
    • 게시글에 접속 후 댓글을 달기

2. 알고리즘

  • 채팅과 유사한 댓글기능에는 댓글 게시글에 부모 게시물이 뭔지도 기록되어 있어야 함
    • = document끼리 종속 관계 맺는 방법임
  • 채팅 기능
    • 버튼 누르면 채팅방 게시물 발행
    • 댓글(메시지) 게시물 남길 수 있게 하면 됨
    • 이때 댓글에는 부모 게시물이 뭔지를 알아야 함

3. 코드

(1) chat.ejs

  • 채팅 페이지 만들기
!<!DOCTYPE html>
<html lang="en">
  <head>
    <!-- Required meta tags -->
    <meta charset="utf-8" />
    <meta
      name="viewport"
      content="width=device-width, initial-scale=1, shrink-to-fit=no"
    />

    <!-- Bootstrap CSS -->
    <link
      rel="stylesheet"
      href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/css/bootstrap.min.css"
      integrity="sha384-xOolHFLEh07PJGoPkLv1IbcEPTNtaed2xpHsD9ESMhqIYd0nLMwNLD69Npy4HI+N"
      crossorigin="anonymous"
    />

    <link rel="stylesheet" href="/public/main.css" />

    <title>Hello, world!</title>
  </head>
  <body>
    <%- include('nav.html') %>

    <div class="container p-4 detail">
      <div class="row">
        <div class="col-3">
          <ul class="list-group chat-list">
            <% for (let i=0; i < data.length; i++){ %>
            <li class="list-group-item" data-id="<%= data[i]._id %>">
              <h6><%= data[i].title %></h6>
              <h6><%= data[i]._id %></h6>
              <h6 class="text-small"><%= data[i].member[0] %></h6>
            </li>
            <% } %>
          </ul>
        </div>

        <div class="col-9 p-0">
          <div class="chat-room">
            <ul class="list-group chat-content">
              <li><span class="chat-box">채팅방1 내용</span></li>
              <li><span class="chat-box">채팅방1 내용</span></li>
              <li><span class="chat-box mine">채팅방1 내용</span></li>
            </ul>
            <div class="input-group">
              <input class="form-control" id="chat-input" />
              <button class="btn btn-secondary" id="send">전송</button>
            </div>
          </div>
        </div>
      </div>
    </div>

    <script
      src="https://code.jquery.com/jquery-3.6.3.js"
      integrity="sha256-nQLuAZGRRcILA+6dMBOvcRh5Pe310sBpanc6+QBmyVM="
      crossorigin="anonymous"
    ></script>

    <!-- Optional JavaScript; choose one of the two! -->

    <!-- Option 1: jQuery and Bootstrap Bundle (includes Popper) -->
    <script
      src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/js/bootstrap.bundle.min.js"
      integrity="sha384-Fy6S3B9q64WdZWQUiU+q4/2Lc9npb8tCaSX9FK7E8HnRr0Jz8D6OP9dO5Vg3Q9ct"
      crossorigin="anonymous"
    ></script>

    <!-- Option 2: Separate Popper and Bootstrap JS -->
    <!--
    <script src="https://cdn.jsdelivr.net/npm/jquery@3.5.1/dist/jquery.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
    <script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js" integrity="sha384-9/reFTGAW83EW2RDu2S0VKaIzap3H66lZH81PoYlFhbGU+6BZp6G7niu735Sk7lN" crossorigin="anonymous"></script>
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/js/bootstrap.min.js" integrity="sha384-+sLIOodYLS7CIrQpBjl+C7nPvqq+FbNUBDunl/OZv93DB7Ln/533i8e/mZXLi/P+" crossorigin="anonymous"></script>
    -->
    <script>
      // 내가 누른 채팅방의 chat collection에서의 게시글ID를 불러옴
      var clickId;
      $(".list-group-item").click(function () {
        $(this).css("background-color", "#eee");
        // 내가 클릭한 채팅방의 data-id 불러오기
        clickId = $(this).attr("data-id");
      });

      // 전송 버튼 클릭했을 때, 채팅 내용을 서버에 보내기
      $("#send").click(function () {
        var 채팅내용 = $("#chat-input").val();
        var 보낼거 = {
          parent: clickId,
          content: 채팅내용,
        };
        // /message라는 URL로 데이터를 전송함
        $.post("/message", 보낼거).then((a) => {
          console.log(a);
        });
      });
    </script>
  </body>
</html>

(2) server.js

  • 요청받은 URL을 통해 데이터를 DB에 저장
// 채팅 기능 코드
app.post("/chatNow", 로그인했니, function (req, res) {
  // user의 id를 불러와서 변수에 저장
  var chatter = req.user._id;
  // 채팅 당한 사람
  var writer = req.body.당한사람id;

  var 작성자 = 0;
  var 저장할거 = {
    title: "머선채팅방",
    member: [ObjectId(writer), chatter],
    date: new Date(),
  };

  db.collection("chat")
    .insertOne(저장할거)
    .then((결과) => {});
});

// 채팅방 접속 코드
app.get("/chat", 로그인했니, function (req, res) {
  db.collection("chat")
    // 로그인한 아이디가 접속중인 채팅방을 찾음
    // chat collection에서 찾음
    .find({ member: req.user._id })
    .toArray()
    .then((결과) => {
      res.render("chat.ejs", { data: 결과 });
    });
});

// 채팅 내용 DB 저장 코드
app.post("/message", 로그인했니, function (req, res) {
  var 저장할거 = {
    // 부모 게시글의 게시글ID를 찾음
    // chat.ejs에서 보내온 데이터 기반임
    parent: req.body.parent,
    content: req.body.content,
    userid: req.user._id,
    date: new Date(),
  };
  // message collection에 채팅 내용을 저장함
  db.collection("message")
    .insertOne(저장할거)
    .then((결과) => {
      console.log("메시지 db저장성공");
      res.send(결과);
    });
});
반응형