Post

웹과 소켓 통신

웹과 소켓 통신

브라우저를 이용해서 웹을 탐색하고 있을 때 아무것도 안 했는데 웹 페이지가 최신화 되거나 알림이 왔다고 표기된 적이 있는가?
이런 경우 클라이언트에서 특정 시간마다 업데이트 된 내역이 있는지 확인하는 Interval을 사용하는 경우도 있지만 좀 더 즉각적인 반응이 필요한 경우에 소켓 통신을 사용하곤 한다.

소켓 통신이라고 하면 C++이나 자바할때나 쓸거 같고 뭐냐고 물으면 우물쭈물하며 제대로 대답 못 할 사람이 많을 것이다. 그래서 오늘은 소켓 통신이란 무엇이며, 웹에서 소켓 통신은 어떻게 사용하는지 알아볼 생각이다.

소켓 통신

소켓 통신의 소켓은 무엇일까? 이 소켓은 네트워크를 통한 통신의 종착점을 뜻한다. 간단히 말해서 서버가 있고, 클라이언트가 있는데 둘 간에 통신을 하는 주체가 각각 소켓이라고 할 수 있다. 이 소켓은 모든 네트워크 통신간의 종착점을 뜻하지만 오늘날 대부분의 통신이 인터넷 프로토콜(IP)를 통해서 이루어지므로 일반적으로 말하는 소켓 통신은 인터넷 소켓 통신이다.

이러한 인터넷 소켓은 아래와 같은 요소로 이루어져 있다.

  • 인터넷 프로토콜 (TCP, UDP, raw IP)
  • 로컬 IP 주소
  • 로컬 포트
  • 원격 IP 주소
  • 원격 포트

이런 요소로 이루어진 종착점 간의 통신을 우리는 인터넷 소켓 통신이라고 부른다. 그렇다면 이러한 방식을 가지고 어떻게 웹에서 사용하느냐, 이건 웹 소켓이라는 기술이 있다.

웹 소켓

말 그대로 웹에서 사용하는 소켓 통신이다. 일반적으로 소켓 통신은 로우 레벨 언어로 짠 코드에서 주로 요구되었지만, 컴퓨터의 성능이 늘어나고 웹 표준이 할 수 있는 영역이 점차 확장됨에 따라 웹에서도 소켓 통신을 할 수 있도록 HTML5 프로토콜에 포함되었다. 즉 브라우저에서 지원하는 Web api라는 뜻이다.

아래와 같은 형태로 사용한다.

1
2
3
4
5
6
7
8
9
10
11
12
// WebSocket 연결 생성
const socket = new WebSocket("ws://localhost:8080");

// 연결이 열리면
socket.addEventListener("open", function (event) {
  socket.send("Hello Server!");
});

// 메시지 수신
socket.addEventListener("message", function (event) {
  console.log("Message from server ", event.data);
});

출처 : https://developer.mozilla.org/ko/docs/Web/API/WebSocket

브라우저에서 지원하는 Web api의 경우 오래된 브라우저일 때 해당 api를 지원하지 않는 경우가 있다. 이럴때는 참 곤란한데 이럴때를 위해서 있는 패키지가 있다. 바로 socket.io이다.

socket.io

오래된 브라우저에서도 소켓 통신을 할 수 있게 해주는 패키지임과 동시에 서버사이드에서도 쉽게 웹 소켓으로 통신 가능한 웹 소켓 서버를 열 수 있게 해주는 패키지이다. 이 패키지가 없다면 nodejs 자체에서 지원하는 API를 엮어서 소켓 통신 하는 모듈을 만들어야 했을 테니 굉장히 곤란했을 것이다.

socket.io는 방금 언급했듯이 client-side와 server-side 두 가지를 지원한다.
다음 코드는 브라우저에서 값을 입력해서 send 버튼을 누르면 서버에 message가 뜨게되는 예시 코드이다. ###Server

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
const express = require('express');
const { createServer } = require('node:http');
const { join } = require('node:path');
const { Server } = require('socket.io');

const app = express();
const server = createServer(app);
const io = new Server(server);

app.get('/', (req, res) => {
    res.sendFile(join(__dirname, 'index.html'));
});

io.on('connection', (socket) => {
    socket.on('chat message', (msg) => {
        console.log('message: ' + msg);
    });
});

server.listen(3000, () => {
    console.log('server running at http://localhost:3000');
});

###Client

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<script src="/socket.io/socket.io.js"></script>
<script>
  const socket = io();

  const form = document.getElementById('form');
  const input = document.getElementById('input');

  form.addEventListener('submit', (e) => {
    e.preventDefault();
    if (input.value) {
      socket.emit('chat message', input.value);
      input.value = '';
    }
  });
</script>

출처 : https://socket.io/docs/v4/tutorial

html 코드는 생략했지만 직관적으로 알 수 있다. 클라이언트에 form이 있고, 데이터를 받을 수 있는 input이 있는데 해당 form에 submit 이벤트가 발생하면 input의 value를 갖고 와 서버에 보내는 식이다.

그렇게 되면 서버에서 connection이 되어있다면 chat message라는 이벤트를 받았을 때 서버에 console.log로 찍는 것이다.

This post is licensed under CC BY 4.0 by the author.