<aside> 💡 Socket.IO를 이용하여, 여러명이 채팅방에 참여하여 실시간 채팅이 가능한 웹 어플리케이션을 만들어 보자.
</aside>
실시간 커뮤니케이션을 도와주는 웹 에플리케이션이다.
//express module 변수에 담기
const express = require("express");
//Node.js기본 모듈 불러오기
const http = require("http");
//cors불러오기
const cors = require("cors");
//express객체 생성
const app = express();
const corsOptions = {
origin: "<http://localhost:3000>",
methods: ["GET", "POST", "OPTION"],
credentials: true,
};
app.use(cors(corsOptions));
//express http서버 생성
const server = http.createServer(app);
//생성된 서버를 socket.io에 바인딩
const io = require("socket.io")(server, {
cors: {
origin: "<http://localhost:3000>",
methods: ["GET", "POST"],
allowedHeaders: ["my-custom-header"],
credentials: true,
},
});
io.on("connection", (socket) => {
**// 여기서 중요한 것은 join이이벤트를 받았을때, socket.join을 실행 시켜주는 것이다.
// 그렇지 않고, connection이 일어날때 바로 socket.join을 하게 되면,
// 총 두번 접속하게 되어, 나중에 접속자 수를 구할때, 2명으로 측정되게 된다.**
socket.on('join', (data) => {
// let { roomId } = socket.handshake.query;
socket.join(data.roomId);
io.to(data.roomId).emit('welcome', `${data.userName} has entered No.${data.roomId} Room`)
})
socket.on('newMessage', (data) => {
console.log(data)
io.to(data.roomId).emit("newMessage", data.newMsg);
})
**//현재 방에 들어와 있는 총 접속자 수를 구하는 부분이다.**
socket.on('getUsers', async (roomId, id) => {
const num = io.sockets.adapter.rooms.get(roomId).size;
console.log(roomId, id)
io.to(roomId).emit('newMessage', `현재 ${num}명이 접속 중입니다.`)
})
socket.on('disconnect', (reason)=>{
socket.emit("newMessage", `User left!! cuz ${reason}`)
})
})
server.listen(8080, () => {
console.log("8080 port is working");
});
import { useState, useEffect}from 'react'
import { useParams} from 'react-router-dom'
import { io } from 'socket.io-client'
const ChatRoom = () => {
const {roomId} = useParams();
const [newMsg, setNewMsg] = useState('');
const [userName, setUserName] = useState('Mark');
const [msg, setMsg] = useState([])
const socket = io('<http://localhost:8080>', {query: {roomId}});
useEffect(() => {
socket.emit('join', ({roomId, userName}));
socket.on('welcome', (data) => console.log(data));
socket.on('newMessage', (data)=>console.log(data));
**//여기서 마지막 return이 의미하는 바는 한번 접속을 하여 일련의 이벤트를 다 처리한 뒤에는
//접속을 종료해 준다는 것이다. 이렇게 하면 자동적으로 접속을 시키려고 하지 않는다.
//만약 마지막에 disconnect를 해주지 않는다면, 접속자수는 기하급수적으로 늘어날 것이고,
//콘솔창이 난리가 나는 상황을 경험해 볼 수 있을것이다.**
return () => socket.disconnect()
}, [])
const nameHandler = (e) => {
setUserName(e.target.value)
}
const magHandler = (e) => {
setNewMsg(e.target.value)
}
const sendMsg = (e) => {
e.preventDefault();
socket.emit('newMessage', {roomId, newMsg})
}
const getUsers = () => {
socket.emit('getUsers', roomId, socket.id)
}
return (
<div>
This is Room
{msg.map(e => {
return (<div>{e}</div>)
})}
<div>
<input type="text" placeholder="name" onChange={nameHandler}/>
<form onSubmit={sendMsg}>
<input type="text" placeholder="msg" onChange={magHandler}/>
<button type="submit">전송</button>
</form>
<button onClick={getUsers}>현재 접속중 인원?</button>
</div>
</div>
)
}
export default ChatRoom