Skip to content
himprover
GitHubVelog

[번역] Socket.IO - 개요, 필요성, 사용 방법

Translate, JavaScript, WebSocket12 min read

banner

이 게시물은 원본 아티클인 Socket.IO - What, Why and How? 를 한글로 번역한 게시글입니다. 게시물 내용의 저작권은 원작자 Shad Mirza 에게 있습니다.

이 게시글은 간단한 웹소켓 시리즈에서 이어지는 두 번째 글 입니다. 만약 첫 번째 글을 읽이 않았다면, 여기에서 확인해보세요. 장담하건데, 첫 번째 글을 읽어야 이번 글을 이해하기 더 나을 것입니다.

왜 Socket.io 인가요?

이전 게시글에서 우리는 성공적으로 기본적인 웹소켓 서버와 클라이언트를 만들고 동작시켰습니다. 그렇다면 대체 왜 socket.io를 써야하는 지 의문이 들텐데요. 왜 이 라이브러리 없어도 잘 동작하는데 굳이 덩치 큰 라이브러리를 사용해야 하는 걸까요? 발생할 수 있는 시나리오를 한번 생각해봅시다.

상사가 웹사이트에 실시간 의사소통 기능 추가를 지시했다고 가정해봅시다. 여러분은 어떤 라이브러리도 사용하지 않고 기본 웹소켓만 사용하기로 결정했습니다.

여러분의 웹소켓 코드는 올바르게 작성됐고, 잘 작동하지만 테스트 결과 몇 가지 문제가 발견됐습니다. 이는 어떤 이유에서인지 항상 올바르게 동작하지 않았습니다.

디버깅을 진행한 후, 해당 문제는 그 사람이 방화벽 이나 백신 프로그램을 사용하고 있을 때 작동하지 않는 것을 확인했습니다. 그래서 여러분은 이것을 깨닫게 됩니다.

웹소켓은 방화벽이나 백신이 있으면 이상적으로 동작하지 않는구나.

또한 클라이언트가 프록시나 로드밸런서를 사용하고 있으면 웹소켓이 동작하지 않는 것도 찾았습니다.

웹소켓은 프록시나 로드밸런서 중 하나를 사용해도 잘 동작하지 않네.

이말인 즉슨, 이러한 모든 이슈를 본인이 직접 해결해야 함을 뜻합니다. 여러분은 몇 시간을 거쳐 추가적인 코드로 모든 문제를 해결하고 웹소켓 연결을 잘 동작하게 만들었습니다. 재현된 이미지를 보며 우리가 얼마나 멀리 갔는지 봅시다.

1

이번에는, 어떤 이유로 서버가 꺼지고 연결이 끊어졌다고 가정해봅시다. 이 상황에서 브라우저는 아무 것도 하고 있지 않습니다. 연결을 다시 성립하기 위해서는 핸드쉐이킹이 필요하기 때문입니다. 따라서 여러분은 한 가지 작업을 더 해보기로 합니다.

서버가 고장나거나 어떤 이유로 연결이 끊어지는 경우에는 자동으로 웹 소켓이 다시 연결되도록 해야겠네.

이제 여러분은 다른 코드를 추가해서 이 문제를 쳐냈습니다. 좋네요. 여러분은 최고의 개발자입니다.

여러분의 상사는 노력한 것에 대해 칭찬했지만, 이번에는 이미지(blobs)를 지원하는 기능도 추가하라는 지시를 받았습니다.

참고 : 지금까지 우리는 JSON 데이터(일반 텍스트)를 전송하고 있었습니다.

이것 뿐만이 아닙니다. 여러분은 그룹 채팅을 위한 채팅방과 여러 개의 엔드포인트도 추가해 여러 개의 웹소켓을 연결해야 합니다. 또한, 일부 오래 된 브라우저의 경우 웹소켓이 동작하지 않아서 직접 처리해주어야 합니다.

이건 정말 많아 보입니다. 그렇지 않나요?

힘들게 작업해서 코드를 추가해서 이것들을 쳐냈습니다. 이제 여러분의 웹소켓 구현부는 아마 이렇게 생겼을 겁니다.

4

알아보니, 이 모든 기능을 포함한 것이 바로 Socket.io로 부르는 겁니다. 이를 사용해 깔끔하게 해결되는 걸 한번 확인해보세요.

5

Socket.io가 뭔가요?

Socket.io 는 웹소켓을 사용하여, 앞서 본 모든 문제들을 우리가 직접 작업하지 않고 해결하게 해줍니다. 이는 기본 웹소켓을 감싸고 있는 래퍼일 뿐이지만, 개발자가 일하기 쉽게 해주는 많은 멋진 기능들을 제공합니다.

정의

Socket.IO는 실시간 웹 어플리케이션을 위한 JavaScript 라이브러리 입니다. 이는 클라이언트와 서버 간의 실시간, 양방향 소통을 가능하게 해줍니다.

Socket.IO는 기본적으로 웹소켓 프로토콜을 사용하며, 폴링을 대체 옵션 제공되면서 동일한 인터페이스를 제공합니다. 단순히 WebSocket의 래퍼로 사용될 수도 있지만, Socket.IO는 여러 소켓에 전파, 각 클라이언트와 관련된 데이터 저장, 비동기 I/O 등 다양한 기능을 제공합니다.

참고: 굵게 적힌 글씨는 주의 깊게 다시 한번 읽어보세요. 우리는 이에 대해 '왜 사용해야 하는지'를 알아볼 때 얘기했습니다. 이제 이해되죠?

이 시리즈의 세 번째 부분에서는 Socket.IO의 핵심 기능을 배워볼 것입니다. 첫 번째 파트에서 작성했던 웹소켓 클라이언트, 서버 파일을 빠르게 Socket.IO로 변환해보겠습니다.

어떻게 하나요?

당신이 첫 번째 파트를 읽고 기본 웹소켓이 어떻게 동작하는지 아고 있다고 가정하겠습니다. 이제 빠르게 Socket.io로 업그레이드 해봅시다.

주석 코드는 웹소켓 사용 부분입니다. 비교를 위해 추가해두었습니다.

서버

const http = require('http');
// const websocket = require('ws');
const socketio = require('socket.io');
const server = http.createServer((req, res) => {
res.end('I am connected');
});
// const wss = new websocket.Server({server});
const io = new socketio(server);
// wss.on('connection', (ws, req) => {
// ws.send('This is a message from server');
// ws.on('message', (msg) => {
// console.log(msg);
// });
// });
io.on('connection', (socket, req) => {
socket.emit('messageFromServer', 'This is a message from server');
socket.on('messageFromClient', (msg) => {
console.log(msg);
});
});
server.listen(8000);

설명

  1. 'ws'로 웹소켓을 불러오는 대신, 'socket.io' 라이브러리에서 socketio를 불러왔습니다
  2. 웹소켓 대신 socketio를 사용해 서버를 만들고 처리합니다.
  3. 'send' 대신 'io' 객체의 'emit' 함수를 사용합니다. 다른 점은 오직 첫 번째 인수로 이벤트명을 추가한 것입니다. 이 이벤트명을 사용해 클라이언트 측에서 메세지를 가져올 것입니다.
  4. 'on' 메서드는 여전히 같은 이름을 사용합니다. 다른 점은 오직 이벤트명이 추가된 것입니다. 간단하죠?

클라이언트

<html>
<head>
<meta charset="utf-8" />
</head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.2.0/scoket.io.js"></script>
<!--socket.io 서버에 연결하기 위해 <script> 태그로 socket.io 라이브러리를 추가합니다.-->
<script>
// let ws = new WebSocket('ws://localhost:8000');
let socket = io('http://localhost:8000');
console.log(socket);
socket.on('connect', (data) => {
// ws.onopen = (event) => ws.send("This is a message from client");
socket.emit('messageFromClient', 'This is a message from client');
// ws.onmessage = (event) => console.log(event);
socket.on('messageFromServer', (message) => {
console.log(message);
});
});
</script>
<body>
<h1>This is client page<h1>
</body>
</html>

설명

  1. JavaScript에서 기본적으로 제공되지 않는 'socket.io' 라이브러리를 불러옵니다. 이렇게 하면 'io' 네임스페이스가 노출됩니다.
  2. 연결을 위해 io에 url을 제공합니다. (웹소켓을 사용할 때 처럼 'new' 키워드를 사용하지 않는 이유는 선택 사항이기 때문입니다. 사용할지의 여부는 여러분의 선택입니다.)
  3. 아까처럼 'send'를 'emit'로 대체하고 이벤트명을 추가합니다. (서버 파트의 21번째 줄 확인)
  4. 'on' 메서드는 여전히 같으며, 이벤트명만 추가해줍니다. (서버 파트의 20번째 줄 확인) 이해되시죠?

짠! 우리는 간단한 Socket.IO 서버와 클라이언트를 만들었습니다.

;

최대한 이것을 간단하게 하기 위해 노력했습니다. Socket.IO에 더 깊게 파고들고자 한다면 이 시리즈의 세번째 파트를 확인해주세요.

출처

Socket.IO Server API - https://socket.io/docs/server-api/

Socket.IO Client API - https://socket.io/docs/client-api/


역주 의견

여기서부터는 저(himprover)의 의견 입니다.

이전에 흥미있게 진행했던 쉬운 웹소켓 시리즈의 2편을 번역했습니다.

아직 3편은 게시되지 않았는데요.

이전과 마찬가지로 약간의 유머도 겸비하며, 복잡하지 않게 설명하는 것이 인상적이었습니다.

언젠가 영어로 아티클을 적게 된다면, 이렇게 외국인도 읽기 쉬운 수준으로 글을 작성해보고 싶네요 :)