[Node.js] 채팅, 귓속말 기능 만들기

2022. 7. 29. 12:22·개발/node.js
728x90
반응형

1. 코드

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>Document</title>
    <script src="/socket.io/socket.io.js"></script>
    <style>
      body {
        height: 100vh;
        position: relative;
      }
      .content {
        position: absolute;
        left: 50%;
        top: 50%;
        transform: translate(-50%, -50%);
        width: 500px;
        min-height: 500px;
        height: auto;
        border: 1px solid black;
      }
      #send {
        position: fixed;
        bottom: 0;
        width: 100%;
        border: 1px solid;
        box-sizing: border-box;
        display: flex;
      }
      #send #msg {
        border: 0;
        box-sizing: border-box;
        padding: 10px;
        width: 90%;
      }
      #send #sendbtn {
        width: 100%;
        background-color: bisque;
        border: none;
        box-sizing: border-box;
        padding: 10px;
        width: 10%;
      }

      #messages {
        list-style-type: none;
        margin: 0;
        padding: 0;
      }
      #messages li {
        padding: 5px 10px;
        word-break: break-all;
      }
      #messages li button {
        border: none;
        box-sizing: border-box;
        background-color: white;
      }

      #login {
        width: 300px;
        height: 300px;
        display: flex;
        align-items: center;
        justify-content: space-evenly;
        position: absolute;
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);
      }
      #main {
        display: none;
      }
      .join_text {
        background-color: gray;
      }
      .leave_text {
        background-color: deepskyblue;
        border: 1px solid rgb(2, 133, 177);
      }
    </style>
  </head>
  <body>
    <div class="content">
      <div>동물(파충류) 카톡</div>
      <div id="login">
        <p>로그인</p>
        <input type="text" id="username" />
        <button id="loginbtn">접속</button>
      </div>
      <div id="main">
        <select id="rooms">
          <option value="병아리 방">병아리 방</option>
          <option value="개구리 방">개구리 방</option>
        </select>
        <ul id="messages"></ul>
        <div id="send">
          <input id="msg" />
          <button id="sendbtn">보냄</button>
        </div>
      </div>
    </div>
  </body>
  <script>
    //클라이언트가 접속하는 함수

    const socket = io.connect();
    window.onload = function () {
      loginbtn.onclick = function () {
        login.style.display = "none";
        main.style.display = "block";
        const name = username.value;
        let room = rooms.options[rooms.selectedIndex].value;
        socket.emit("joinRoom", room, name);

        //귓속말 전용 공간 만들기
        socket.emit("forWhisperRoom", name);

        rooms.onchange = function (e) {
          let el = e.target;
          socket.emit("leaveRoom", room, name);
          room = rooms.options[rooms.selectedIndex].value;
          socket.emit("joinRoom", room, name);
        };
        //들어올때
        socket.on("joinRoom", (room, name) => {
          messages.innerHTML += `
          <li class="join_text">
              ${name}님이 ${room}에 들어오셨습니다.
          </li>
          `;
        });
        //나갈때
        socket.on("leaveRoom", (room, name) => {
          messages.innerHTML += `
          <li class = "leave_text">
              ${name}님이 ${room}에서 나갔습니다.
          </li>
          `;
        });

        //입력한 메시지 띄우기
        let messageLi = document.querySelectorAll(".messageLi");
        socket.on("chat", (name, msg) => {
          messages.innerHTML += `
          <li>
              <button class = "messageLi">${name}</button> : ${msg}
          </li>
          `;
          messageLi = document.querySelectorAll(".messageLi");
          whisperFun();
        });

        //메시지 입력
        sendbtn.onclick = function () {
          if (msg.value == "") {
            return;
          }

          //귓속말일때
          if (msg.value.match(/^\/w/i)) {
            let whisperId = msg.value.replace(/^\/w /i, "").split(/\s/)[0];
            let whisperMsg = msg.value
              .replace(/^\/w /i, "")
              .split(/\s/)
              .splice(1)
              .join(" ");
            socket.emit("whisperchat", room, name, whisperMsg, whisperId);
          } else {
            //기본
            socket.emit("chat", room, name, msg.value);
          }
          msg.value = "";
        };
        msg.onkeydown = function (e) {
          if (msg.value == "") {
            return;
          }
          if (e.keyCode == 13) {
            //귓속말일때
            if (msg.value.match(/^\/w/i)) {
              let whisperId = msg.value.replace(/^\/w /i, "").split(/\s/)[0];
              let whisperMsg = msg.value
                .replace(/^\/w /i, "")
                .split(/\s/)
                .splice(1)
                .join(" ");
              socket.emit("whisperchat", room, name, whisperMsg, whisperId);
            } else {
              //기본
              socket.emit("chat", room, name, msg.value);
            }
            msg.value = "";
          }
        };

        //귓속말
        //아이디 누르면 자동 귓속말 입력
        function whisperFun() {
          for (let i = 0; i < messageLi.length; i++) {
            messageLi[i].onclick = function () {
              msg.focus();
              msg.value = `/w ${this.innerText} `;
            };
          }
        }

        //서버에서 귓속말 관련 받는 부분
        socket.on("whisperchat", (room, name, whisperMsg, whisperId) => {
          messages.innerHTML += `
            <li>
              ${room}에 있는 <button class = "messageLi">${name}</button> 님으로부터온 귓속말 : ${whisperMsg}
            </li>
          `;
          messageLi = document.querySelectorAll(".messageLi");
          whisperFun();
        });
      };
    };
  </script>
</html>

js

const express = require("express");
//아래코드로 서버의 몸체가 되는 객체만 만들어지고
const app = express();
const PORT = 3000;

//아래코드로 서버를 3000번 포트에서 듣고있게한다. =대기상태
const server = app.listen(PORT, () => {
  console.log("Server Start");
});
//socket io 생성및 실행
const socketio = require("socket.io");
const io = socketio(server);
// "/socket.io/socket.io.js"경로로 js파일에 접근할수 있다

const fs = require("fs");

app.get("/", (req, res) => {
  fs.readFile("page.html", "utf-8", (err, data) => {
    res.send(data.toString());
  });
});

// 클라이언트가 접속 했을때 connection
// socket.on => 등록
io.on("connect", (socket) => {
  console.log("유저 접속");
  socket.on("joinRoom", (room, name) => {
    //방개념으로 접속시켜주는 함수 join(방이름)
    socket.join(room);
    // to(room) : 현재 그 방에 있는 클라이언트에게 요청
    io.to(room).emit("joinRoom", room, name);
  });

  socket.on("leaveRoom", (room, name) => {
    //방개념으로 떠나게 해주는 함수 leave(방이름)
    socket.leave(room);
    io.to(room).emit("leaveRoom", room, name);
  });

  socket.on("chat", (room, name, msg) => {
    io.to(room).emit("chat", name, msg);
  });

  //귓속말
  //귓속말 공간 들어가기
  socket.on("forWhisperRoom", (name) => {
    socket.join(name);
  });
  socket.on("whisperchat", (room, name, whisperMsg, whisperId) => {
    socket.to(whisperId).emit("whisperchat", room, name, whisperMsg, whisperId);
  });
});

 

2. 결과

아이디를 만들때 각 아이디로 된 room에 들어간다.

귓속말은 그 room으로 메시지를 보내는것

728x90
반응형

'개발 > node.js' 카테고리의 다른 글

[Node.js] 로그인시 jwt과 session  (0) 2022.08.09
[Node.js] 로그인시 JWT생성  (0) 2022.08.09
[Node.js, jquery] 비행기 예약 시스템 만들기  (0) 2022.07.29
[Node.js] socket.io 로 채팅방 만들기  (0) 2022.07.26
[Node.js] 삭제, 수정버튼 만들기  (0) 2022.07.26
'개발/node.js' 카테고리의 다른 글
  • [Node.js] 로그인시 jwt과 session
  • [Node.js] 로그인시 JWT생성
  • [Node.js, jquery] 비행기 예약 시스템 만들기
  • [Node.js] socket.io 로 채팅방 만들기
TeTedo.
TeTedo.
  • TeTedo.
    TeTedo 개발 일기
    TeTedo.
  • 전체
    오늘
    어제
    • 분류 전체보기 (319)
      • 개발 (274)
        • Article (4)
        • 정리 (21)
        • Spring Boot (17)
        • JPA (2)
        • JAVA (6)
        • Database (4)
        • 자료구조 (11)
        • 알고리즘 (32)
        • React (20)
        • Docker (10)
        • node.js (18)
        • Devops (11)
        • Linux (4)
        • TypeScript (3)
        • Go (10)
        • HyperLedger (4)
        • BlockChain (43)
        • html, css, js (48)
        • CS (3)
        • AWS (3)
      • 모아두고 나중에 쓰기 (3)
      • 팀프로젝트 (18)
        • SNS(키보드워리어) (9)
        • close_sea (9)
      • 개인프로젝트 (1)
        • Around Flavor (1)
        • CHAM (13)
        • ethFruitShop (5)
      • 독서 (0)
        • 스프링부트와 AWS로 혼자 구현하는 웹 서비스 (0)
  • 블로그 메뉴

    • 홈
    • 개발일기
    • CS
    • 실습
    • 코딩테스트
    • 웹
    • Go
    • node.js
    • 팀플
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    node.js
    html
    30일챌린지
    nodejs
    컨테이너
    erc20
    ERC721
    30일 챌린지
    명령어
    js
    node
    go언어
    도커
    mysql
    블록체인
    go
    React
    하이퍼레저
    CSS
    프로그래머스
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.1
TeTedo.
[Node.js] 채팅, 귓속말 기능 만들기
상단으로

티스토리툴바