본문 바로가기

네트워크 공부

Websocket 개념 정리

학교 동아리에서 수기로 일일히 출석체크를 하는 시스템이 빡세다고 운영진 측의 의견이 있었다.

 

그래서 서버 측에서 서버를 열면, 그 시간 동안 들어온 클라이언트들이 출석번호같은 문자를

입력하고, 출석을 인증하는 웹앱을 만들고 싶었다.

 

그 때, 같이 작업하던 친구가 사용했던 방식이 웹소켓이었다.

 

웹소켓에 대한 개념이 전무했기 때문에 새로 공부하며 그에 대한 내용을 여기 정리하려고 한다.

 

웹소켓 (WebSocket)

웹소켓 프로토콜은 HTTP와는 다른 통신 프로토콜로 웹 서버와 웹 브라우저가 서로 실시간 메시지를

교환하는 데에 사용된다.

웹소켓 연결을 맺기 위한 첫 번째 핸드쉐이크를 주고받은 이후에 지속적으로 연결이 유지되어

추가적인 HTTP 연결 요청을 보낼 필요가 없어 빠르고 효율적이다.

 

예를 들어, 웹 상에서 구글 Docs를 이용해 여러 사용자가 동시에 한 문서를 편집하고 있다면

새로고침을 누르지 않아도 실시간으로 다른 사용자가 편집한 부분이 자동으로 적용되는 모습을

볼 수 있다. 이와 같은 기술이 WebSocket을 이용한 기술이다.

 

웹소켓은 TCP 소켓과 이름만 유사할 뿐, 브라우저의 소켓이며, 웹소켓 프로토콜은 HTTP와 동일하게 애플리케이션 계층에서 동작한다.

 

최초 접속시에는 HTTP 프로토콜을 이용해 핸드셰이킹을 한다. 이후 연결이 맺어지면 어느 한쪽이 연결을 끊지 않는

이상 영구적인 동일한 채널이 맺어지고 HTTP 프로토콜에서 웹소켓 프로토콜로 변경된다.

웹소켓이 제공하는 4가지 이벤트

  • open: 커넥션이 제대로 생성되었을 때 발생하는 이벤트
  • message: 데이터를 수신하였을 때 발생하는 이벤트
  • error: 에러가 발생했을 때 이벤트
  • close: 커넥션이 종료되었을 때 발생하는 이벤트

 

javascript로 웹소켓 사용 예시

// 웹소켓 생성
const socket = new WebSocket("wss://dummydata.or.kr");

// 커넥션이 제대로 생성되었을 때
socket.onopen = function (e) {
    let data = {
        action: "good",
        subscribe: "test",
    };
    socket.send(JSON.stringify(data))
};


let result;
let price;

// 데이터를 수신 받았을 때
socket.onmessage = async function (e) {
    try {
        if (e !== null && e !== undefined) {
            result = await JSON.parse(e.data);
            price = result[0];
            document.getElementById("test").innerHTML = `$ ${price}`
        }
    } catch (err) {
        console.log(err);
    }
};

// 에러가 발생했을 때
socket.onerror = function (e) {
    console.log(e);
};

 

* socket.io 란?

socket.io는 실시간 웹 어플리케이션을 위한 JavaScript 라이브러리입니다.

웹 클라이언트와 서버간에 실시간 양방향 통신이 가능합니다.

브라우저에서 실행되는 클라이언트 측 라이브러리와 Node.js용 서버 측 라이브러리 두부분으로 구성됩니다.

 

* 환경 구축하기

express를 이용해 서버를 구축합니다.

npm install express-generator -g
express --no-view

 

그 후 

npm install
npm start

이 코드를 차례대로 입력

 

그 후, 명령어를 통해 socket.io를 설치한다.

npm install --save socket.io

 

* 클라이언트 코드 작성

//public/index.html

<html>

<head>
  <title>Express</title>
  <link rel="stylesheet" href="/stylesheets/style.css">
  <script defer src="/socket.io/socket.io.js"></script>
  <script defer src="javascripts/socket.js"></script>
</head>

<body>
  <ul id="messages" id="chat-form"></ul>
    <form action="">
      <input id="m" autocomplete="off" /><button>Send</button>
    </form>
</body>

</html>
//public/javascripts/socket.js

const socket = io();

 

* 서버 코드 작성

Node.js의 HTTP Server에 socket을 연결시킬 것이다.

//bin/www

var app = require('../app');
var debug = require('debug')('socket-example:server');
var http = require('http');

var port = normalizePort(process.env.PORT || '3000');
app.set('port', port);

var server = http.createServer(app);
var io = require('socket.io')(server);

io.on('connection', (socket) => {
  console.log('a user connected');
});

server.listen(port);

...

 

 

다음 포스팅에는 이 코드를 좀 더 정교하게 다듬어서 실제 채팅기능을 웹에 넣어볼 것이다.

 

참조

https://yozm.wishket.com/magazine/detail/1911/

https://code-lab1.tistory.com/300

https://beautify-log.tistory.com/95

https://jinhyukoo.github.io/js/2020/12/05/socket.io%ED%86%B5%EC%8B%A0.html