실시간 GIF 채팅방 만들기(1)
사람들이 익명으로 생성하고 자유롭게 참여하면서 GIF 파일을 올릴 수 있는 채팅방을 만들어보겠습니다.
몽고디비와 몽고디비 ODM인 몽구스를 사용할 것입니다. 몽구스를 설치한 후, 몽구스 스키마를 생성하겠습니다. 채팅방 스크마와 채팅 내역 스키마만 있으면 됩니다. 사용자는 익명이니 딱히 저장할 필요가 없습니다. 사용자의 이름은 랜덤 색상으로 구별하겠습니다.
먼저 필요한 모듈을 설치합니다. 이미지를 업로드하고 서버에 HTTP 요청을 할 것이므로 multer와 axios를 같이 설치합니다. color-hash 모듈은 조금 전에 언급했던 랜덤 색상을 구현해주는 모듈입니다.
$ npm i mongoose multer axios color-hash
먼저 채팅방 스키마를 만들어보겠습니다.
schemas/room.js
const mongoose = require("mongoose");
const { Schema } = mongoose;
const RoomSchema = new Schema({
title: {
type: String,
required: true,
},
max: {
type: Number,
required: true,
default: 10,
min: 2,
},
owner: {
type: String,
required: true,
},
password: String,
creadtedAt: {
type: Date,
default: Date.now,
},
});
module.exports = mongoose.model("Room", RoomSchema);
방 제목(title), 최대 수용 인원(max), 방장(owner), 비밀번호(password), 생성 시간(createdAt) 등을 받습니다. 수용 인원은 기본적으로 10명, 최소 인원은 2명 이상으로 설정합니다. 채팅방에 혼자 있으면 아무 의미가 없으니까요. 비밀번호는 required 속성이 앖으므로 꼭 넣지 않아도 됩니다. 비밀번호를 설정하면 비밀방, 설정하지 않으면 공개방입니다.
이번에는 채팅 스키마를 만듭니다.
schemas/chat.js
const moongoose = require("mongoose");
const { Schema } = moongoose;
const {
Types: { ObjectId },
} = Schema;
const ChatSchema = new Schema({
room: {
type: ObjectId,
required: true,
ref: "Room",
},
user: {
type: String,
required: true,
},
chat: String,
gif: String,
createdAt: {
type: Date,
default: Date.now,
},
});
module.exports = moongoose.model("Chat", ChatSchema);
채팅방 아이디(room)와 채팅을 한 사람(user), 채팅 내역(chat), GIF 이미지 주소(img), 채팅 시간(createdAt)을 지정합니다. room 필드는 Room 스키마와 연결하여 Room 컬렉션의 ObjectId가 들어가게 됩니다. chat 또는 img 필드에 required 속성이 없는 이유는 채팅 메시지나 GIF 이미지 중에서 하나만 저장하면 되기 때문입니다.
다음은 몽고디비와 연결하는 코드입니다.
schemas/index.js
const mongoose = require("mongoose");
const { MONGO_ID, MONGO_PASSWORD, NODE_ENV } = process.env;
const MONGO_URL = `mongodb://${MONGO_ID}:${MONGO_PASSWORD}@localhost:27017/admin`;
const connect = () => {
if (NODE_ENV === "production") {
mongoose.set("debug", true);
}
mongoose.connect(
MONGO_URL,
{
dbName: "gifchat",
useNewUrlParser: true,
useCreateIndex: true,
},
(error) => {
if (error) {
console.log("몽고디비 연결 에러", error);
} else {
console.log("몽고디비 연결 성공");
}
},
);
mongoose.connection.on("error", (error) => {
console.error("몽고디비 연결 에러", error);
});
mongoose.connection.on("disconnected", () => {
console.error("몽고디비 연결이 끊겼습니다. 연결을 재시도합니다.");
connect();
});
};
module.exports = connect;
.env
COOKIE_SECRET=gifchat
MONGO_ID=입력
MONGO_PASSWORD=****
보안을 위해 아이디와 비밀번호를 procees.env로 분리했습니다. 또한, 데이터베이스의 이름이 gifchat으로 바뀌었스빈다.
서버를 실행할 때는 몽고디비에 바로 접속할 수 있도록 서버와 몽구스를 연결합니다.
app.js
const express = require("express");
const path = require("path");
const cookieParser = require("cookie-parser");
const session = require("express-session");
const nunjucks = require("nunjucks");
const dotenv = require("dotenv");
dotenv.config();
const webSocket = require("./socket");
const indexRouter = require("./routes");
const morgan = require("morgan");
const connect = require("./schemas");
const app = express();
app.set("port", process.env.PORT || 8005);
app.set("view engine", "html");
nunjucks.configure("views", {
express: app,
watch: true,
});
connect();
app.use(morgan("dev"));
app.use(express.static(path.join(__dirname, "public")));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser(process.env.COOKIE_SECRET));
app.use(
session({
resave: false,
saveUninitialized: false,
secret: process.env.COOKIE_SECRET,
cookie: {
httpOnly: true,
secure: false,
},
}),
);
app.use("/", indexRouter);
app.use((req, res, next) => {
const error = new Error(`${req.method} ${req.url} 라우터가 없습니다.`);
error.status = 404;
next(error);
});
app.use((err, req, res, next) => {
res.locals.message = err.message;
res.locals.error = process.env.NODE_ENV !== "production" ? err : {};
res.status(err.status || 500);
res.render("error");
});
const server = app.listen(app.get("port"), () => {
console.log(app.get("port"), "번 포트에서 대기 중");
});
webSocket(server);
'프로그래밍 언어 > NODE JS' 카테고리의 다른 글
| 실시간 GIF 채팅방 만들기(3) (0) | 2026.01.26 |
|---|---|
| 실시간 GIF 채팅방 만들기(2) (0) | 2026.01.23 |
| Socket.IO 사용하기 (0) | 2026.01.17 |
| ws 모듈로 웹 소켓 사용하기 (0) | 2026.01.14 |
| ws 모듈로 웹 소켓 사용하기 (0) | 2026.01.11 |