room/:puzzleID/랜덤주소
로 구성했다.
socket.join(랜덤주소)
에 쓰인다. 그럼 특정 주소 내에서만 원하는 통신을 할 수 있다.room/:puzzleID/랜덤주소
로 들어간다. 이 주소로 들어오는 사람들은 서로 채팅을 할 수 있다.
소켓연결
//socket.tsx
export const socket = io(`${process.env.REACT_APP_ROOT_URL}`);
export const SocketContext = React.createContext(socket);
//play-puzzle/index.tsx
import { SocketContext, socket } from "@src/context/socket";
useEffect(() => {
setPuzzle(); //puzzle 정보 fetch
socket.emit("joinRoom", { roomID: roomID });
return () => {
socket.emit("leaveRoom", { roomID: roomID });
};
}, []);
return (
<SocketContext.Provider value={socket}>
<Chat chatVisible={chatVisible} roomID={roomID} />
</SocketContext.Provider>
)
//chat.tsx
import { SocketContext } from "@src/context/socket";
const Chat = (props: any) => {
const { roomID, chatVisible } = props;
const socket = useContext(SocketContext);
...
}
방 퇴장
socket.leave('해당랜덤주소')
한다. 해당랜덤주소
방의 클라이언트가 삭제된다.해당랜덤주소
방의 클라이언트가 삭제된다.setInterval
로 10분마다 io.sockets.adapter.rooms.get(roomURL 집합의 원소들)
로 client 수를 파악한다. client 수가 0인 랜덤 주소는 roomURL
집합에서 삭제된다.import { clear } from 'console';
import { roomURL } from './roomInfo';
const updateRoomURL = (io: any) => {
const cb = (io: any) => {
let mySet = new Set<string>();
const _roomURL = Array.from(roomURL);
for (let item of _roomURL) {
const clients = io.sockets.adapter.rooms.get(item);
const numClients = clients ? clients.size : 0;
if (numClients === 0) mySet.add(item);
}
mySet.forEach(item => roomURL.delete(item));
};
setInterval(cb, 60000, io);
};
export default (io: any) => {
console.log('socket 연결!');
io.on('connection', (socket: any) => {
updateRoomURL(io);
socket.on('joinRoom', (res: { roomID: string }) => {
socket.join(res.roomID);
});
socket.on('message', (res: { roomID: string; message: object }) => {
io.sockets.in(res.roomID).emit('message', res.message);
});
socket.on('leaveRoom', (res: { roomID: string }) => {
socket.leave(res.roomID);
});
socket.on('disconnect', () => {});
});
};