본문 바로가기
개발/개인, 사이드 프로젝트

Express, React, Mongoose 로 웹소켓 채팅앱 만들기. 4 [채팅방 추가]

by 코딩하는짱구 2023. 11. 8.
반응형

Express, React, Mongoose 로 웹소켓 채팅앱 만들기. 4 [채팅방 추가]

 

1. chat, user table 완성 후 socket으로 front-back 상호작용 연결하기

2023.10.13 - [개발관련/개인프로젝트] - Express, React, Mongoose 로 웹소켓 채팅앱 만들기. 1

 

Express, React, Mongoose 로 웹소켓 채팅앱 만들기. 1

쇼핑몰 애플리케이션에서 간단하게 구현해봤던 웹소켓을 이용해서 간단한 채팅앱을 구현해보기로 했다. Express, React, Mongoose 로 웹소켓 채팅앱 만들기. 1 1. 어떻게 만들 것인가? 2. 오늘 겪은 문제

veritas-crystal.tistory.com

 

2. user login 기능 구현, user 정보 전달/저장

2023.10.19 - [개발관련/개인프로젝트] - Express, React, Mongoose 로 웹소켓 채팅앱 만들기. 2

 

Express, React, Mongoose 로 웹소켓 채팅앱 만들기. 2

Express, React, Mongoose 로 웹소켓 채팅앱 만들기. 2 1탄에서 socket 으로 프론트/백 연결까지 했으니, 이제는 user login 기능을 구현해야한다. 1. Today I learned 2. 오늘 겪은 문제 위의 목차를 클릭하면 해당

veritas-crystal.tistory.com

 

3. chat 기능 구현

2023.11.02 - [개발관련/개인프로젝트] - Express, React, Mongoose 로 웹소켓 채팅앱 만들기. 3

 

Express, React, Mongoose 로 웹소켓 채팅앱 만들기. 3

Express, React, Mongoose 로 웹소켓 채팅앱 만들기. 3 1. chat, user table 완성 후 socket으로 front-back 상호작용 연결하기 2023.10.13 - [개발관련/개인프로젝트] - Express, React, Mongoose 로 웹소켓 채팅앱 만들기. 1 Ex

veritas-crystal.tistory.com

 

지난 시간에 채팅기능 까지 구현에 성공했다. 

오늘은 채팅방을 만들어서 채팅방 입장, 퇴장까지 구현했는데, 생각보다 많은 난관에 부딪혔다. 

user가 채팅방을 직접 만들 수 있도록 설계하면 좋겠지만 아직은 무리가 있어서 과제에서 미리 만들어둔 room 을 가지고 구현했다.

 

Express, React, Mongoose 로 웹소켓 채팅앱 만들기. 4 [채팅방추가]

1. 채팅방 model, io, controller 셋팅

2. 오늘 겪은 문제

위의 목차를 클릭하면 해당 글로 자동 이동 합니다.

 

1. 채팅방 model, io, controller 셋팅

우선 room 의 model을 설정하고, user, chat model에도 room 항목을 만들어주었다. 

 

room 은 고유의 ObjectId를 가진다. 

//Models/room.js
const mongoose = require('mongoose');

const roomSchema = new mongoose.Schema(
  {
    room: String,
    members: [
      {
        type: mongoose.Schema.ObjectId,
        unique: true,
        ref: 'User',
      },
    ],
  },
  { timestamp: true }
);
module.exports = mongoose.model('Room', roomSchema);

 

 

해당 room에 chat이 저장되어야 하므로 room 추가

//Models/chat.js
const mongoose = require('mongoose');

const chatSchema = new mongoose.Schema(
  {
    chat: String,
    user: {
      id: {
        type: mongoose.Schema.ObjectId,
        ref: 'user',
      },
      name: String,
    },
    room: {
      type: mongoose.Schema.ObjectId,
      ref: 'Room',
    },
  },
  { timestamp: true }
);

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

 

방에 입장한 user 또한 room 정보를 가져야 하기에 추가

//Models/user.js
const mongoose = require('mongoose');

const userSchema = new mongoose.Schema({
  name: {
    type: String,
    required: [true, 'User must type name'],
    unique: true,
  },
  token: {
    type: String,
  },
  online: {
    type: Boolean,
    default: false,
  },
  room: {
    type: mongoose.Schema.ObjectId,
    ref: 'Room',
  },
});

module.exports = mongoose.model('User', userSchema);

이렇게 room data를 database에 추가하게 되었으면 이 정보를 client가 알아야한다.

방법은? 백엔드에서 controller를 통해 room 정보를 긁어오고, socket을 통해 프론트로 전달한다.

 

controller에서 getAllrooms 를 통해 roomList를 반환하고, 

const Room = require('../Models/room');

const roomController = {};

//채팅방 목록 불러오기
roomController.getAllRooms = async () => {
  const roomList = await Room.find({});
  return roomList;
};

소켓을 통해 getAllrooms로 얻어진 roomList를 client에게 전달한다! 😎

반복해보니 이제 백엔드-소켓-프론트엔드의 관계가 명확해진다.

module.exports = function (io) {
  // io 관련된 모든 일
  io.on('connection', async (Socket) => {
    console.log('client connection', Socket.id);

    Socket.emit('rooms', await roomController.getAllRooms());

이 후 같은 방식으로 roomController.joinRoom 함수를 통해 채팅방 입장 기능까지 구현했다. 

  1. roomController.checkUser 를 통해 socket.id로 저장된 user를 확인
  2. roomController.joinRoom(rid, user)를 통해 user를 해당 방에 입장 시킨다
  3. Socket.join을 통해 사용자의 Socket도 해당 room 에 join 시킨다. 
  4. 사용자가 참여한 후에 다시 roomController.getAllrooms()를 통해 업데이트 된 채팅방을 보여준다.

 

2. 오늘 겪은 문제

1. pages/Chatpage/Chatpage.jsx 위치 

front 에서 chat

 

2. unique index 제약 조건 위반

 

반응형