[Node.js] 채팅 앱 개발

한별·2023년 12월 1일

Node.js

목록 보기
5/5

백엔드 세팅

필요한 라이브러리들 설치

$ npm init -y

-> package.json 파일 생성

npm i express, mongoose, cors dotenv http nodemon
  • express: 서버를 만든다. express 서버에 DB를 올림.
  • mongoose: mongo DB를 쉽게 사용할 수 있도록 함
  • cors: 프론트, 백 통신에 문제 없도록
  • dotenv: 설치한 환경 변수를 들고옴
  • http: http 서버에 웹소켓을 올림.
  • nodemon: javascript 파일을 실행해준다 (node와 유사). 파일에 변화가 생기면 자동 리로딩을 해줌
$ npm i socket.io

DB 세팅

메시지 스키마 만들기

스키마: 데이터의 설계도

const mongoose = require("mongoose");

const chatSchema = new mongoose.Schema(
  {
    content: String,
    user: {
      id: {
        type: mongoose.Schema.ObjectId,
        ref: "User",
      },
      nickname: String,
    },
  },
  { timestamp: true }
);

module.exports = mongoose.model("Chat", chatSchema);

서버 만들기 + DB 연결

// app.js
const express = require("express");
const mongoose = require("mongoose");
const app = express();

mongoose
  .connect("데이터베이스 주소", {
    useNewUrlParser: true,
    useUnifiedTopoloty,
  })
  .then(() => {
    console.log("connected to database");
  });

module.exports = app;

환경 변수 파일

DB 주소는 중요, 변화함 → 환경 변수 파일에 관리

// .env
PORT = 5001
DB = mongodb://localhost:27017/chatchat
// app.js
require("dotenv").config();

mongoose.connect(process.env.DB)

CORS 세팅

// app.js
const cors = require("cors");

app.use(cors());

웹소켓 세팅

// index.js
const { createServer } = require("http");
const app = require("./app");
const { Server } = require("socket.io");
require("dotenv").config();

const httpServer = createServer(app);
const io = new Server(httpServer, {
  cors: {
    origin: "http://localhost:3000"
  },
});

httpServer.listen(process.env.PORT, () => {
  console.log("server listening on port", process.env.PORT);
});

io 파일 분리

// utils/io.js
module.exports = function (io) {
  // io 관련 작업 (emit, on)
}
// index.js
require("./utils/io")(io);

connection 확인

연결된 사람의 정보인 socket이 parameter로 들어온다

module.exports = function (io) {
  io.on("connection", async (socket) => {
    console.log("client is connected", socket.id);

    socket.on("disconnect", () => {
      console.log(`user(${socket.id}) is disconnected`);
    });
  });
};

프론트엔드 세팅

필요한 라이브러리 설치

$ npm i socket.io-client
// server.js
import { io } from "socket.io-client";
const socket = io("http://localhost:5001"); // 연결하고 싶은 백엔드 주소
export default socket;
// 소켓 통신을 사용할 화면
import socket from "../server";

연결 테스트

백엔드: nodemon index.js
프론트엔드: npm start

프론트엔드를 새로고침하면 백엔드 콘솔에 다음과 같은 메시지가 뜬다.

client is connected ${socket_id}

채팅 기능 구현

BE - Controller

const Chat = require("../Models/chat");
const chatController = {};

chatController.saveChat = async (message, user) => {
  const newMessage = new Chat({
    content: message,
    user: {
      id: user._id,
      nickname: user.nickname,
    },
  });
  await newMessage.save();
  return newMessage;
};

module.exports = chatController;

+) Chat.findOne({ attribute : value }) 를 이용하면 해당하는 Data를 조회한다

BE - io

const UserController = require("../Controllers/user");
const ChatController = require("../Controllers/chat");

module.exports = function (io) {
  // io 관련 작업 (emit, on)
  io.on("connection", async (socket) => {
    console.log("client is connected", socket.id);

    // 어떤 User가 메시지를 보냈을 때
    socket.on("sendMessage", async (message, callback) => {
      try {
        const user = await UserController.checkUser(socket.id);
        const newMessage = await ChatController.saveChat(message, user);
        // 다른 User들에게 message를 알려줌
        io.emit("message", newMessage);
        callback({ ok: true });
      } catch (error) {
        callback({ ok: false, error: error.message });
      }
    });
  });
};

FE - 메시지 받기

  useEffect(() => {
    socket.on("message", (message) => {
      setMessages((prevState) => prevState.concat(message));
    });
  }, []);

FE - 메시지 보내기

  const sendMessage = (message: string) => {
    if (message === "") return;
    socket.emit("sendMessage", message, (res: SendMessageResType) => {
      if (!res?.ok) {
        alert(res?.error);
      }
    });
  };

참고 자료

[YouTube][코딩알려주는 누나] 채팅앱 만들기 | 웹소켓이란 뭘까?| 풀스택으로 만들어보자
[YouTube][코딩알려주는 누나] 웹소켓을 이용해 채팅앱을 만들어보자! | 유저 로그인편
[YouTube][코딩알려주는 누나] 어떻게 메세지를 주고받을까? | 웹소켓을 이용해 채팅앱을 만들어보자!

profile
글 잘 쓰고 싶어요

0개의 댓글