WebSocket과 Socket.io 차이점
알아보게 된 배경
최근까지 회사에서 외부 프로젝트의 프론트엔드단을 Vue.js로 구현했는데, 기능 중에 실시간 CCTV 영상을 조회하고 영상을 제어하는 부분이 있었다.
그 기능의 프론트엔드 부분을 구현하다가 영상을 받아오고 제어할 때 웹소켓을 사용한다는 것을 알게 되었다.
웹소켓이라는 개념은 처음 알게 되어서 좀 더 알아보고자 노마드코더의 줌 클론코딩을 진행하다가 WebSocket과 Socket.io 차이점을 정리하고 싶어서 글을 쓰게 되었다.
WebSocket 등장하게 된 이유

WebSocket을 지원하는 브라우저

자세한 내용은 https://developer.mozilla.org/en-US/docs/Web/API/WebSocket 여기서 확인해보면 된다.
WebSocket vs Socket.io
기본적으로 API 구성은 두 가지 모두 비슷하다.
하지만, Socket.io의 API는 WebSocket API의 불편한 사항을 많이 개선해놓았다고 봐도 무방하다.
그럼 어떤 사항들이 개선되어서 Socket.io API에 반영되었을까?
1) 커스텀 이벤트 가능
// WebSocket
wss.on("connection", (socket) => { // 여기서 socket은 연결된 브라우저를 뜻함
sockets.push(socket);
socket["nickname"] = "Anon"
console.log("Connected to Browser ✅");
// 새로운 브라우저가 접속하게 되면 socket.on 코드가 실행됨
socket.on("close", () => console.log("Disconnected from the Browser ❌")) // frontend에서의 close 이벤트를 listen 하는 것 = 브라우저 탭을 닫으면 (브라우저 연결이 끊기면) 실행
socket.on("message", (msg) => { // 브라우저가 서버에 메세지를 보냈을 때를 위한 listener
프론트엔드에서 백엔드로 메세지를 보낼 때, WebSocket의 경우는 이벤트를 반드시 "message"로 주어야 한다.
// Socket.io
wsServer.on("connection", socket => {
socket.on("enter_room", (msg) => console.log(msg));
});
하지만, Socket.io의 경우는 개발자가 "message"가 아닌 원하는 이름으로 커스텀 이벤트로 등록할 수 있다.
2) 프론트엔드에서 Object도 전송할 수 있다.
// WebSocket
function makeMaessage(type, payload) {
const msg = {type, payload};
return JSON.stringfy(msg);
}
WebSocket에서 프론트엔드에서 백엔드로 메세지를 보낼 때는 JSON을 String을 바꿔줘야 하는 번거로움이 있다.
WebSocket은 String만 받을 수 있기 때문!
// Socket.io
function handleRoomSubmit(event) {
event.preventDefault();
const input = form.querySelector("input");
socket.emit("enter_room", { payload: input.value });
input.value="";
}
하지만, Socket.io에서는 Object로 메세지를 보내도 Socket.io가 알아서 처리를 해주는 장점이 있다.
3) 필요한 만큼 argument를 전송할 수 있다.
// 프론트엔드
function handleRoomSubmit(event) {
event.preventDefault();
const input = form.querySelector("input");
socket.emit(
"enter_room",
{ payload: input.value },
7,
"hello",
true
);
input.value="";
}
// 백엔드
wsServer.on("connection", socket => {
socket.on("enter_room", (msg, a, b, c) => {
console.log(msg, a, b, c);
});
});

Socket.io는 다음과 같이 argument를 여러개 전송하고 받을 수 있다.
4) 백엔드에서 프론트엔드 함수를 실행시킬 수 있다.
// frontend
function handleRoomSubmit(event) {
event.preventDefault();
const input = form.querySelector("input");
socket.emit("enter_room", input.value, backendDone);
input.value="";
}
// backend
wsServer.on("connection", socket => {
socket.on("enter_room", (roomName, done) => {
console.log(roomName);
setTimeout(() => {
done("hello from the backend");
}, 15000);
});
});
frontend의 socket.emit에서 맨 마지막 argument를 함수로 주게 되면 backend에서 받아서 그 함수를 직접 실행시킬 수 있게 된다.
참고로 stackoverflow에 누군가 상세하게 WebSocket과 Socket.io를 비교해놓은 답변이 있다.
개인적으로 코드 비교부터 네트워크 트래픽 비교까지 해놓아서 유용하게 참고했다.
https://stackoverflow.com/questions/10112178/differences-between-socket-io-and-websockets%EF%BB%BF
Differences between socket.io and websockets
What are the differences between socket.io and websockets in node.js? Are they both server push technologies? The only differences I felt was, socket.io allowed me to send/emit messages by
stackoverflow.com
관련 코드
https://github.com/Jung-Ah-C/zoom-clone-coding
참고 문헌
https://d2.naver.com/helloworld/1336
https://stackoverflow.com/questions/10112178/differences-between-socket-io-and-websockets