[리액트] 실시간 채팅 구현하기 (socket.io, Nodejs) - 2
[리액트] 실시간 채팅 구현하기 (socket.io, Nodejs) - 1
https://www.youtube.com/watch?v=ZwFA3YMfkoc 위 영상을 기반으로 제작합니다. Client 세팅 (CRA) create-react-app을 통해 client 쪽을 세팅한다. 서버는 Nodejs express를 사용할 것이다. 리액트 라우터를 설치해주고 Join
ryuwc.tistory.com
1탄에 이어 글을 작성한다.
Client
먼저, 아래의 라이브러리들을 설치해준다.
npm i query-string
npm i socket.io-client
클라이언트 에서 socket 설치
npm i react-emoji
이모지를 사용하기위해 설치
npm i react-scroll-to-bottom
버튼을 누르면 최신으로 이동하기 위해 설치
이때 현재 최신의 socket버전과 영상의 버전 차이가 있기 때문에 오류가 뜬다.
socket버전을 client, server 둘 다 아래와 같이 package.json에서 버전을 내려준다.
node_module 충돌이 날 경우 노드모듈 폴더를 삭제하고 다시 npm i 를 터미널에서 친다.
유튜브의 내용을 따라갈 것이기 때문에 편의상 css는 아래의 파일을 사용한다.
Join.js의 내용을 다음과 같이 작성한다.
import React, {useState} from 'react';
import {Link} from "react-router-dom";
import './Join.css';
function Join() {
const [name, setName] = useState('')
const [room, setRoom] = useState('')
return (
<div className='joinOuterContainer'>
<div className='joinInnerContainer'>
<h1 className='heading'></h1>
<div>
<input
placeholder='이름'
className='joinInput'
type='text'
onChange={(event) => setName(event.target.value)}
/>
</div>
<div>
<input
placeholder='채팅방'
className='joinInput mt-20'
type='text'
onChange={(event) => setRoom(event.target.value)}
/>
</div>
<Link
onClick={(e) => (!name || !room ? e.preventDefault() : null)}
to={`/chat?name=${name}&room=${room}`}
>
<button className={'button mt-20'} type='submit'>
가입
</button>
</Link>
</div>
</div>
);
}
export default Join;
components 폴더안에
InfoBar, Input, Messages, TextContainer 폴더를 생성하고 다음과 같이 만들어준다.
css 파일은 편의를 위해 아래의 첨부 파일을 사용한다.
생성한 컴포넌트들에 일단 다음과 같이 구별할 수 있게만 간단히 작성해준다.
import React from 'react';
import './InfoBar.css';
function InfoBar() {
return (
<div>
인포바
</div>
);
}
export default InfoBar;
이제 Chat.js 파일을 다음과 같이 작성한다.
import React, {useState, useEffect} from 'react';
import queryString from 'query-string';
import io from 'socket.io-client';
import './Chat.css';
import InfoBar from "../components/InfoBar/InfoBar";
import Messages from "../components/Messages/Messages";
import TextContainer from "../components/TextContainer/TextContainer";
import Input from "../components/Input/Input";
const ENDPOINT = 'http://localhost:5000';
let socket;
function Chat() {
const [name, setName] = useState('');
const [room, setRoom] = useState('');
const [users, setUsers] = useState('');
const [message, setMessage] = useState('');
const [messages, setMessages] = useState([]);
useEffect(() => {
const {name, room} = queryString.parse(window.location.search);
socket = io(ENDPOINT);
setName(name);
setRoom(room);
socket.emit('join', {name, room}, (err) => {
if (err) {
alert(err);
}
});
return () => {
socket.emit('disconnect');
socket.off();
}
}, [ENDPOINT, window.location.search]);
useEffect(() => {
socket.on('message', (message) => {
setMessages([...messages, message]);
});
socket.on('roomData', ({users}) => {
setUsers(users);
});
}, []);
const sendMessage = (event) => {
event.preventDefault();
if (message) {
socket.emit('sendMessage', message, () => setMessage(''));
}
}
return (
<div className='outerContainer'>
<div className='container'>
<InfoBar room={room} />
<Messages messages={messages} name={name} />
<Input
message={message}
setMessage={setMessage}
sendMessage={sendMessage}
/>
</div>
<TextContainer users={users} />
</div>
);
}
export default Chat;
Server
server/index.js 가서 통신이 되도록 코드를 수정해준다.
const express = require('express')
const socketio = require('socket.io')
const http = require('http')
const cors = require('cors')
const router = require('./router')
const PORT = process.env.PORT || 5000
const app = express();
const server = http.createServer(app)
const io = socketio(server)
app.use(cors())
app.use(router)
io.on('connection', (socket) => {
console.log('새로운 유저가 접속했습니다.')
socket.on('join', ({name, room}, callback) => {})
socket.on('disconnect', () => {
console.log('유저가 나갔습니다.')
})
})
server.listen(PORT,()=>console.log(`서버가 ${PORT} 에서 시작되었어요`))
server 폴더 내에 router.js 파일을 생성하여 다음과 같이 작성한다.
const express = require('express')
const router = express.Router()
router.get('/', (req, res) => {
res.send({ response: "I am alive" }).status(200)
})
module.exports = router
cors 문제를 해결하기 위해 cors와 실시간으로 채팅이 보여지도록 nodemon을 설치해 준다.
server 에서 설치
npm i cors
npm i -D nodemon
package.json에 start 부분을 추가한다.
npm run start를 실행해 서버를 돌린다.
이제 Join에서 이름과 채팅방을 입력하며 Chat으로 접속하면 server터미널에 다음과 같이 뜰 것이다.
현재 Chat 페이지는 다음과 같다.
다음편에 이어서 작성하겠다.