-> 이 경우 두 이벤트의 이름을 똑같이 맵핑해줘야 한다.
서버 수신 - 클라 발신 시 보내고 받는 그 '이름'이 같아야 하고, 서버 발신 - 클라 수신의 이름이 같아야 한다. 지금 이 경우는 chat-message
라는 이름으로 맵핑 되고있다.
// 서버 수신
socket.on('chat-message', (data) => {
// 서버 발신
io.emit('chat-message', { id: socket.id, msg: data });
});
// 클라이언트 발신
socket.emit('chat-message', message); // 서버로 메시지 전송
// 클라이언트 수신
socket.on('chat-message', ({ id, msg }) => {
// ... 비즈니스 로직
};
-> 코드가 왜 이런 형태로 쓰이냐면 공식문서에서 이게 기본 형태라고 안내하고 있기 때문이다. 당장은 낯설겠지만 익숙해지는 것이 좋을듯🤔
-> 나중 가면 바이트 배열 형태로 데이터를 보내는 '버퍼객체' 라는 걸 배우게 될 거다. 나중에 TCP 서버 공부하면 알게될 것.
-> ~.on
: 나 받는다
~emit
: 나 발신한다
이 방식에서는 무조건 event라는 이름으로 주고받기 때문에 이름으로 구분할 수는 없다.
-> 다만 이 안에서 핸들러 번호 맵핑을 잘 해야 한다. event라는 이름 하나 안에서 여러 개로 쪼개지기 때문.
const handlerMapping = {
11: () => {
// 비즈니스 로직
},
};
const handleEvent = (io, socket, { handlerId, data }) => {
const handler = handlerMapping[handlerId];
// 적절한 핸들러가 없다면 실패처리합니다.
if (!handler) {
socket.emit('response', { status: 'fail', message: 'Handler not found' });
return;
}
const response = handler(io, socket, data);
io.emit('response', { status: 'success', handlerId, data: response });
};
socket.on('event', (data) => handleEvent(io, socket, data));
대충 이런식으로 코드가 생겼을 것이다. 핸들러 맵핑을 봤을 때 특정 핸들러가 11번에 맵핑되어 있다는 얘기.
-> 왜 섞어쓰는게 중요하냐면, 'monster-event' 라는 이름 안에 있는 핸들러가 한 20개 정도 되고 'user-event' 안에 있는 핸들러가 한 30개 정도 되는 식의 구조가 될 것이다. 이름으로 한번 분류하고, 기능에 따라 핸들러 번호를 맵핑하는 식으로 내부에서 또 나누게 될 것. 어느 한 방식만 쓰는 데에는 한계가 있기 때문.
-> 이때 response에서 클라이언트한테 handlerId는 왜 주냐면,
C++이나 C#은 원하는 구조대로 오지 않으면 읽지도 못한다. 특히 C++은 원하는 구조 아니면 에러를 터트린다. (젠장...)
io.attach(server);
로 서버를 붙인다. (웹소켓 서버 오픈!)
io.on('connection', (socket) => {}
로 'connection'이라는 이름으로 socket을 인자로 받는다.
일단 서버는 io.emit()
을 쓴다. 둘이 뭐가 다르냐?
socket.emit()은 이 연결을 한 클라이언트 한명에게만 답장을 해주는 것.
io.emit()은 이 소켓의 전체 유저에게 답장을 뿌려주는 것.
-> 이 io.emit()은 진짜로 모든 서버 전체 유저에게 보내는 것이다!
그래서 서버단인 socket.js에서는 11번인 sendMessage라고 되어 있고,
클라단인 script.js에서는 sendMessage인 11번이라고 되어있다.
왜 찾을 수 없다는거야? 🤔🤔🤔🤔🤔
-> HTML의 오타 때문이었다...... 😭😭😭😭😭
역시 기대를 저버리지 않는 인파님의 블로그. 여기를 참고