Woowa Techcourse/Missions

Frontend를 위한, Socket과 WebSocket

mingule 2021. 8. 26. 10:55

들어가기

Web Socket.. 많이 들어봤지만, 들을 때마다 친구들의 곡소리가 끊이지 않던 친구였다. 

그래서인지 괜히 '웹소켓'이라는 말을 들으면 지레 겁부터 먹었었다.

한 번 공부해보고 싶은 주제였지만, 지금껏 딱히 사용할 기회가 없었기도 해서(변명변명).. 웹소켓은 점점 더 멀어져갔다.

 

그런데! 이번에 레벨3 팀 프로젝트 중, 피터가 제안한 '태그 기반의 게임 팀 매칭 서비스'에서 채팅을 메인으로 다룬다고 했다.

서비스 자체도 재미있을 것 같았고, 웹소켓에 대한 알 수 없는 도전정신이 나를 지배해 이 팀에 지원하게 되었다.

지원한 결과, 감사하게도 뽑기 신께서 도움을 주셔서 Babble 팀에 합류할 수 있게 되었다. 후헹헹ㅎㅎ

 

이제 Babble 프론트엔드 팀이 채팅을 구현하면서 WebSocket에 대해 공부한 내용에 대해 살짝 이야기해보겠다. 헤헹

🔌 Web Socket은 뭐야, 아니 그전에 Socket이 뭐야?

Socket의 뜻을 검색해보면, 아래와 같이 나온다.

이 뜻을 생각하면서 네트워크에서의 Socket이 뭔지 한 번 유추해보자.

다른 부분이 들어갈 수 있도록 만들어 놓은 구멍,

서로 다른 어떤 것들이 서로 연결될 수 있도록 만들어놓은 창구 정도로 해석할 수 있다.

즉, 컴퓨터에서 프로그램이 네트워크에서 데이터를 통신할 수 있도록 연결해주는 친구이다. 

 

콘센트를 한 번 생각해보자. 내가 아무런 구멍이 없는 벽에 백번 코드를 넣으려 한다 해도, 전기를 사용할 수 없을 것이다.

마찬가지로 보내는 쪽(Client Socket), 받는 쪽에(Server Socket) 모두 Socket이 열려 있어야 그 Socket을 통해 데이터를 보내고, 받을 수 있다. 여기에서 Client는 우리가 사용하는 컴퓨터, Server는 AWS에 있는 서버 컴퓨터를 생각하면서 글을 읽으면 한결 이해하기 쉽다.

 

🖥 Socket Programming

프로세스 간 통신에 사용되는 Socket을 이용한 통신 프로그래밍을 Socket Programming이라고 한다.

이제부터 Socket Programming에 대해 알아보겠다.

Client Socket과 Server Socket

그러면 Client Socket과 Server Socket은 각각 무슨 역할을 할까?

통신 연결 요청을 받아들이는 Socket을 Server Socket,

통신 연결 요청을 보내는 Socket을 Client Socket이라고 한다.

동일한 구조의 Socket이지만, 역할에 따라 처리되는 흐름이 조금씩 다르다.

 

Client Socket의 처리 흐름 (컴퓨터)

Client Socket이 처리되는 흐름은 아래와 같다.

1. Client Socket 생성

  - 연결 대상에 대한 정보가 들어있지 않은 껍데기 Socket을 생성한다.

 

2. 연결 요청(Connection)

  - 연결하고싶은 대상한테 '연결해줘!' 라고 요청을 보낸다. IP 주소와 Port 번호로 연결하고 싶은 대상을 특정한다.

  - 요청을 보낸다고 끝나는 것이 아니고, 그 요청에 대한 결과가 돌아와야지 Connect의 실행이 끝난다.

 

3. 데이터의 송수신 (Send, Recieve)

  - 이 또한 연결 요청처럼, 요청을 보낸다고 끝나는 것이 아니고 그 요청에 대한 결과가 들어와야 실행이 끝난다.

  - 하지만 송수신 간의 차이점은 존재한다.

    - 송신(Send)할 때에는 데이터를 보내는 것이기 때문에 데이터를 언제, 얼마나 보낼 것인지를 알 수 있다.

    - 수신(Recieve)할 때에는 상대방이 언제, 얼만큼의 데이터를 보낼 것인지 알 수가 없다.

    - 그렇기 때문에 수신하는 API는 별도의 Thread에서 진행하게 된다.

 

4. Socket 닫기 

  - 더 이상의 데이터 송수신이 필요없어지게되면, 소켓을 닫는다. 

 

Server Socket의 처리 흐름

Server Socket이 처리되는 흐름에 대해 알아보기 전에! 먼저 살짝 Socket과 Port에 관해 알아보자.

 데이터를 송수신함에 있어서 중요한 건 뭐다?!! 뭐다?!! 보안이다.

내가 A에게 카톡을 보내면, 동네방네 카톡이 돌아다니는 게 아니라, A의 카톡에 잘 도착해야한다.

내가 내 사진을 웹사이트에 올리면, 다른 웹사이트가 아니라 내가 올리려고 한 그 웹사이트에 사진이 올라가야한다.

 

이렇게 내가 어떤 데이터를 전송한다고 했을 때, 받는 입장에서 무작정 데이터를 수신하는 것이 아니라

데이터를 받을 호스트의 프로세스 레벨에서 어떤 프로세스가 이 데이터를 받아야하는 지 판단하고나서 데이터를 수신한다. 

※ 호스트 - 네트워크 주소(IP 주소)가 할당된 Node (인터넷에 연결된 애들이라고 보면 편하다)

※ Node - 네트워크에 연결된 모든 종류의 장치

 

그럼 이 프로세스가 그 특정한 프로세스인지 어떻게 식별할까? 바로 Port로 식별한다.

Port는 이렇게 네트워크를 통해 데이터를 주고받을 때, 프로세스를 식별하기 위해 호스트 내부적으로 프로세스가 할당받는 고유한 값이다.

데이터를 보낼 때, 데이터의 목적지에 Port를 입력해 전달한다.

그렇게 데이터가 도착하면, 목적지에 적힌 Port 번호를 가지고있는 프로세스를 찾아 데이터를 슉 전달한다. 

이 프로세스는 양방향이다. 즉, 데이터를 보낼 때에도 Port 번호가 필요하다.

왜냐하면! 데이터를 받아 요청한 내용을 처리해서 응답을 다시 보내주려면 또 그 프로세스를 식별하기 위해 Port가 필요하기 때문이다.

프로세스를 식별할 때 Port를 사용한다는 것에 유념하면서 Server Socket의 처리과정을 한 번 알아보자. 

Port에 대해 100% 이해하지 못했더라도 아래 흐름을 읽다보면 조금 더 이해가 잘 될 것이다. 호호호 (아니면죄송합니다)

 

1. Server Socket 생성 (socket)

  - Client Socket 생성 시와 마찬가지로, 연결 대상에 대한 정보가 들어있지 않은 껍데기 Socket을 생성한다.

 

2. Server Socket 바인딩 (bind)

  - Socket과 Port 번호를 바인딩한다.

     이게 당최 뭔소리냐.. 싶으실 수 있겠지만 .. 조금 더 설명해 보겠읍니다..

     우리는 컴퓨터를 사용하면서 한 번에 한가지 일만 하는게 아니라, 엄청나게 많은 일을 한꺼번에 한다.

     (물론 한 가지 일만 할 수도 있겠찌만 헤헷)

     인강을 켜놓고 카카오톡을 켜고 친구와 대화하면서, 웹 브라우저를 열어 Babble에 들어가 익명의 유저들과 채팅을 하기도 하고..

     엄청나게 다양한 일을 할 것이다. (하나에 집중을 못하는 나의 모습과 닮아있따)

     이렇게 되면, 컴퓨터에서는 많은 프로세스가 돌아가게 된다.

     우리가 자주 쓰는 Activity Monitor, 즉 작업 표시창을 켜보면 이렇게 컴퓨터에서 돌아가는 수많은 프로세스들을 확인할 수 있다. 

 

     컴퓨터에서 A부터 Z까지의 프로세스가 돌아간다고 가정하자.
     이렇게 돌아가는 다양한 프로세스 중에 프로세스 A, B, C, D, E 가 네트워크 관련 기능을 수행한다고 또 가정해보자.

     이 중, A, C, D가 데이터의 송수신에 관련된 프로세스를 다룬다면,

     각 프로세스에서 사용하는 Socket은 데이터를 송수신하기 위한 Port 번호를 사용하게 된다.

     (이 Port 번호는 프로토콜 표준에 따라 시스템이 관리하는 포트 중 하나의 포트번호를 사용하게 된다.)

     그런데 만약 A 프로세스의 Socket이 사용하는 Port 번호와, C 프로세스의 Socket이 사용하는 Port 번호가 같게된다면 어떻게 될까?

     데이터가 도착했는데 A 프로세스로 보내줘야할지, C 프로세스로 보내줘야 할 지 혼란이 오게 될 것이다.

     그렇기 때문에 Server Socket이 고유한 Port 번호를 만들 수 있도록 Socket과 Port 번호를 결합(Bind)해주는 작업이 꼭 필요하다.

 

     근데, 여기서 궁금한 점! 

     그럼 하나의 프로세스는 Socket, 즉 연결 창구를 하나만 연결할 수 있을까?

     그렇지 않다. 하나의 프로세스는 같은 Port를 가진 Socket을 여러개 열 수 있다. 

     호스트 A가 하나의 Port로 여러 개의 Socket을 만들어 다른 호스트들과 데이터를 주고받을 수 있다.

     이러한 이유 덕분에 우리가 하나의 채팅 앱을 사용하더라도 동시에 많은 사람들과 채팅을 주고받을 수 있는 것이라고 생각한다.

     '그루밍'이라는 Port가 Socket을 1, 2, 3, 4 ... 개 열어서 Socket1로는 피터, Socket2로는 포츈, Socket3으로는 와일더 ..

     이렇게 대화할 수 있게 되는 것이다. 

 

3. Client 연결 요청 대기 (listen)

  - Server Socket에서 Port번호와 바인딩 작업을 마치고 나면, 드디어! Client로부터의 연결 요청을 받아들일 준비가 되었다.

  - Client가 연결 요청을 할 때까지 계속 기다리고 있는다. (이런 역할을 Listen 한다고 한다. 나 귀기울이고 있어~~!!)

  - 이렇게 대기상태를 계속 지속하다가, 연결 요청이 오면 대기 상태를 종료하고 리턴한다. (아직 연결이 된 건 아니다!)

 

4. Client 연결 수립 (accept)

  - listen은 정말 기다리고 있다가 들리는 게 있으면 어 요청이 들린다! 하고 종료! 리턴! 하는게 끝이고, 실질적인 연결은 여기에서 된다.

     도데체 왜일까?

     accept 단계에서는 최종적으로 연결 요청을 받아들이고, Socket 간의 연결을 수립한다. 
     여기까지 들으면, 충분히 listen 단계에서도 할 수 있을거라 생각이 드는데, 중요한 이유가 있다. 
     accept 단계에서는 최종 요청을 받아들이면서, 새로운 Socket을 생성한다! 뚜둔! 

     당연히 Socket 간 연결이라고 했을 때, 당연히 Client - Server 간의 연결이겠찌?!! 했는데, 아니다. 

     Server Socket의 메인 역할은 Client의 연결 요청을 받는 것이었다! 그래서 계속 Client가 오기를 오매불망 기다렸던 것!

     연결 요청을 받고 accept를 통해 새로 생성된 Socket과 Client Socket을 매핑해주면 Server Socket의 역할은 끝이 난다. 
     (그렇기 때문에 Client Socket에 대한 내용을 Server Socket은 단순히 받아서 새로 생기는 Socket에게 넘겨주기만 한다.)

     역할이 끝나면 Server Socket은 다시 다른 연결 요청을 처리하기 위해 대기(listen)하거나, Server Socket을 닫는다(close).

 

5. 데이터의 송수신 (Send, Recieve)

  - 이 또한 Client Socket과 같다. 하지만 또 써준다.

     연결 요청처럼, 요청을 보낸다고 끝나는 것이 아니고 그 요청에 대한 결과가 들어와야 실행이 끝난다.

  - 하지만 송수신 간의 차이점은 존재한다.

    - 송신(Send)할 때에는 데이터를 보내는 것이기 때문에 데이터를 언제, 얼마나 보낼 것인지를 알 수 있다.

    - 수신(Recieve)할 때에는 상대방이 언제, 얼만큼의 데이터를 보낼 것인지 알 수가 없다.

    - 그렇기 때문에 수신하는 API는 별도의 Thread에서 진행하게 된다.

 

6. Socket 닫기 

  - 더 이상의 데이터 송수신이 필요없어지게되면, 소켓을 닫는다.

  - 그런데 여기에서 중요한 점은, Server Socket은 자기 자신만 관리하는 게 아니라, Client와의 연결 수립에서 생성된 

    새로운 Socket에 대해서도 관리를 해주어야 한다는 거다. 너가 만들었으니까 너가 관리햇!

 

이렇게 Client Socket, Server Socket의 역할을 통해 Socket Programming에 대해 알아보았다. . . 

이제 드디어 Socket에 대해 좀 이해가 갔다. . . 험난한 여정이었따 . . 따흑 . . .

 

그러면 . . . 도데체 . . . Web Socket은 뭘까?!

 

🕸🔌 드디어, WebSocket!

그러면 WebSocket은 뭘까? 

WebSocket은 Web에서 두 프로그램 간의 메시지를 교환하기 위한 통신 방법 중 하나이다.

뒤에 Socket이 달려있어서 위에 나온 Socket과 같은거 아니야?! 라고 생각할 수 있지만, 두 개념은 엄연히 다르다.

 

WebSocket은 위의 Socket과는 IP, Port 통신을 한다는 점에서는 비슷하지만, 분명한 차이가 있다. 간단히 설명해보겠다.

웹 브라우저는 HTTP Protocol을 사용한다. 즉, 요청을 보내면 응답이 오는 단방향적 구조로 통신한다.

그렇기 때문에 TCP/IP(데이터 송수신) Protocol을 사용하는 Socket처럼 계속 connection이 유지되는 실시간 통신을 할 수가 없다.

이런 실시간 통신의 문제점을 해결하기 위해 나온 것이 WebSocket Protocol이다.

Web Socket이 나오기 전에도 HTTP Protocol 방식으로도 실시간 통신인 척 하게 만들 수는 있었지만

사용하기에 한계가 많아 WebSocket이 등장하게 되었다. (이와 관련한 내용은 아래에 따로 적겠다.)

 

WebSocket을 사용하면, 웹 브라우저에서도 Socket 통신을 하는 것처럼 실시간으로 데이터를 주고받을 수 있다.

최근에는 대부분의 브라우저가 WebSocket 프로토콜을 지원하지만, IE의 경우는 10 이상의 버전부터 지원한다. 

웹소켓 지원 브라우저 / 출처: https://caniuse.com/websockets

🏗 WebSocket의 동작 방법

그러면, 이제 WebSocket의 동작 방법을 한 번 알아보자.

1. HandShaking 🤝

우리 연결하자!

죠아! 악수! 땅땅! 

Browser와 Server의 연결을 시작하게 해주는 단계를 Handshake 단계라고 한다.

최초로 접속할 때에 HTTP Protocol 위에서 HandShaking을 하기 때문에, HTTP Header를 사용한다.

(좌) https://ko.javascript.info/websocket / (우) google..

WebSocket을 호출해 Socket을 생성하면 즉시 연결이 시작되고, 

이러한 연결이 유지되는 동안, 브라우저는 Header를 통해 Server에 WebSocket을 지원하는지 물어본다.

이때 서버가 맞다는 응답을 하면, 그때부터 HTTP Protocol 대신 WebSocket Protocol로 통신된다.

 

어떻게 통신하는지 보다 자세히 살펴보자.

WebSocket은 위에 언급했다시피 HTTP와는 다르지만, HTTP Protocol과 호환된다.

이러한 호환성을 달성하기 위해 WebSocket handshake는 

HTTP Upgrade header를 사용해 HTTP Protocol 내의 WebSocket Protocol로 변경된다. 

 

어떻게 변경될까? 아래를 살펴보자.

아래는 Babble에서 채팅을 연결할 때 사용하는 request header이다. 

Protocol을 바꾸고 싶다는 신호를 아래와 같이 보내고있다.

Connection: Upgrade - Client 측에서 Protocol을 Upgrade(바꾸자!)하고 싶다는 신호를 보냈다는 걸 뜻함

Upgrade: websocket - 어떤 걸로 Upgrade 시키고 싶은가? websocket으로 바꾸고 싶다는 것!

 

요 두가지를 꼭 작성해줘야, WebSocket으로 통신하자는 요청을 보낼 수 있다.

Sec-WebSocket-Key는 브라우저에서 보안을 위해 랜덤하게 생성한 Key를 나타내는데, Server는 이 Key를 바탕으로 

Token을 생성한 후, 브라우저에게 돌려준다.

 

Client에서 이렇게 요청하면, 이에 대한 응답으로 handshake 응답을 받는다.

이 때, 서버가 Protocol 전환을 승인하면 🟢 응답코드 101이 들어오게 된다.

그렇게 데이터 통신이 시작된다. 

 

- 한 줄 요약

WebSocket을 사용하겠다는 HTTP 요청을 하고 OK 승인을 받으면

통신 규약을 HTTP에서 websocket으로 upgrade시키고,

socket을 뚫어 그 socket으로 데이터를 주고받을 수 있게 한다는 것이다. 헤헷

 

2. Data Transfer - 데이터 전송 🗂

1번의 Handshake를 통해 WebSocket 연결이 되면, 이제부터 데이터를 송수신 할 수 있다.

Client와 Server가 메시지로 데이터를 주고받는데, 이 메시지는 Frame이라는 한 개 이상의 데이터 조각으로 구성되어 있다.

이 Frame은 Server, Client 양 측에서 모두 보낼 수 있는데, 종류가 다양하다.

텍스트가 담긴 텍스트 프레임,

바이너리 데이터가 담긴 바이너리 데이터 프레임, 

커넥션이 유지되는지 확인하기 위한 핑/퐁 프레임.. 등이 있다.

일단 우리는 WebSocket을 사용할 것이기 때문에 WebSocket에서 사용하는 칭구들만 알고있으면 된다. 하하!

 

WebSocket의 send() 메서드는 텍스트나 바이너리 데이터만 보낼 수 있기에 브라우저 환경에서 개발자는 텍스트 프레임이나 바이너리 프레임만 다루게 된다. 

 

3. Close Handshake ✋ 🤚

데이터의 송수신이 완료되면, Client와 Server 모두 Connection을 종료하기 위한 Frame을 전송할 수 있다.

Connection을 종료하고 싶은 쪽에서 Connection을 종료한다는 Frame을 보내면, 상대쪽에서 응답으로 Close Frame을 전송한다. 

이렇게 WebSocket 연결이 종료된다.

 

🚨 But..  WebSocket의 한계

이렇게 뭔가 완벽(?)해보이는 WebSocket에도 한계는 분명히 존재한다.

 

1. 일단 기존의 HTTP로 구현된 Polling, Long Polling, Streaming 방식에 비해 구현이 복잡하다.

2. HTML5 이후에 나왔기 때문에, HTML5 이전의 기술에는 적용이 어렵다. 즉, WebSocket을 지원하지 않는 브라우저가 존재한다.

3. Stateless한 HTTP와는 달리, WebSocket은 Stateful한 Protocol이므로 연결을 항상 유지해야 한다. 

    이러한 연결 자체도 비용일 뿐더러,

    항상 연결이 정상적으로 동작한다는 보장이 없기 때문에 비정상적으로 연결이 끊기게 되는 상황에 대한 대응책이 필요하다.

 

     ※ Stateless - Server Side에 Client와 Server의 동작이나 상태 정보를 저장하지 않는 형태. Client의 Session 상태와 관계없이 요청에 대한 응답만을 수행한다. 단일 요청에 대해 하나의 응답만이 나온다.

     ※ Stateful - Server Side에 Client와 Server의 동작이나 상태 정보를 저장하는 형태. Client의 Session 상태에 따라 Server의 응답이 달라진다. 현재의 상태가 이전의 상태에 영향을 받는다.

 

💪 한계를 극뽁해보자!

WebSocket이 가진 한계 중에, "HTML5 이전의 기술에 적용이 어렵다" 는 문제에 대한 해결책으로 나온 몇가지 방법이 있다.

1. Socket.io

https://socket.io/

 

Socket.IO

SOCKET.IO 4.0 IS HERE ~/Projects/tweets/index.js const io = require('socket.io')(80); const cfg = require('./config.js

socket.io

https://github.com/socketio/socket.io

 

GitHub - socketio/socket.io: Realtime application framework (Node.JS server)

Realtime application framework (Node.JS server). Contribute to socketio/socket.io development by creating an account on GitHub.

github.com

Socket.io는 Node.js 기반으로 만들어진 기술로 Javascript를 이용해

브라우저의 종류에 상관없이 실시간 통신을 구현할 수 있도록 한 라이브러리이다. 

 

브라우저가 WebSocket을 지원하면 그대로 WebSocket 방식으로 동작하고,

지원하지 않는 브라우저면 HTTP Protocol을 이용해 실시간 통신을 흉내낸다.

 

Node.js를 기반으로 만들어진 기술이기 때문에, Server는 다른 대안 없이 Node.js를 사용해야 한다.

개인들이 만들어 놓은 몇가지 방법이 있다고는 하지만.. 완전한 방법은 아니므로 추천하지는 않는다.

 

반면, Client는 Socket.io에서

Javascript 뿐만 아니라 Java, C++ 등에서 사용할 수 있도록 지원해주고 있다.

2. Sock.js

sockjs.org

 

GitHub - sockjs/sockjs-client: WebSocket emulation - Javascript client

WebSocket emulation - Javascript client. Contribute to sockjs/sockjs-client development by creating an account on GitHub.

github.com

SockJS도 Socket.io와 마찬가지로 브라우저의 종류와 관계없이 실시간 통신을 구현할 수 있도록 한 라이브러리이다. 

 

마찬가지로 브라우저가 WebSocket을 지원하면 우선적으로 WebSocket 방식으로 동작하고,

사용할 수 없는 경우에는 다양한 브라우저 별 전송 프로토콜을 사용해 WebSocket처럼 동작한다. 

 

여기까지 보면, Socket.io와 크게 다르지 않아 보이지만, 몇가지 다른 점이 존재한다.

먼저, Spring Framework 자체에서 WebSocket을 사용할 때

구형 브라우저에 대한 대비책으로 SockJS Protocol을 사용하고 있다. 

 

https://docs.spring.io/spring-framework/docs/4.1.7.RELEASE/spring-framework-reference/html/websocket.html

SockJS Protocol은 브라우저 내의 SockJS-client와 SockJS-server 사이에 통신을 하기 위해 만들어진 규약이다.

 

(잠깐 Protocol의 정의에 대해 짚고 넘어가자면, 아래와 같다.

Protocol의 정의는 컴퓨터 간의 데이터 통신을 하기 위한 통신 규약이다.

google.com

즉, Protocol은 컴퓨터 간 통신을 하기 위한 약속인거다.)

 

이렇듯 Spring Framework에서의 WebSocket이 SockJS Protocol을 준수하고 있기에, 

Backend에서 Spring Framework를 사용하고 있다면

Frontend에서도 자연스럽게 SockJS-client를 사용하는 것이 자연스럽다.

 

Babble 팀도 현재 Backend에서 Spring Framework를 사용하고 있기에,

Frontend에서도 자연스럽게 SockJS-client를 사용해 구현하게 되었다. 

 

 


💌 Text 기반 메시징 Protocol, Stomp

Stomp는 Simple Text Oriented Messaging Protocol의 약자로, 간단한 Text 중심의 메시징 Protocol이다. 

 

앞서 우리는 WebSocket을 통해 메시지(형식: Text/Binary)를 주고받을 수 있다는 것을 알았다. 

하지만 WebSocket 자체는 양방향 데이터 전송을 위한 프로토콜일 뿐, 

WebSocket만을 이용해 채팅을 구현하게 되면 해당 메시지가 어떤 요청인지, 어떤 포맷으로 오는지,

메시지 통신 과정을 어떻게 처리해야 하는 지 정해져 있지 않아 일일히 정해주어야한다.

 

이러한 불편함을 줄여주고자, 메시지 전송을 효율적으로 만들어주는 Stomp가 나오게 되었다.

 

Stomp는 한 마디로, 

WebSocket 상에서 동작하며 Client와 Server가 서로 통신하는 데 있어서

메시지의 형식, 유형, 내용 등을 정의해주는 Protocol이라고 할 수 있다.

 

Stomp를 사용하면 아래와 같은 장점이 있다.

1. WebSocket에서 메시지가 어떤 형식으로 사용될 지 지정해준다.

2. WebSocket의 Session 관리를 도와준다.

3. 발행과 구독이라는 개념을 도입해서, 우리가 어떻게 메시지를 통신할 건지에 대한 과정을 정해뒀다.

    WebSocket에는 발행이나 구독같은 개념이 따로 없기 때문에, 우리가 이런 상황을 예측하고 일일히 다 설계해놔야한다.

4. Stomp를 이용하면 메시지에 Header를 줄 수 있기 때문에 Header를 기반한 인증 처리가 가능하다.

5. Stomp의 규칙을 잘 지킨다면 여러 언어 및 플랫폼 간의 메시지를 처리할 수 있다는 장점이 있다.

 

그리고 Stomp version 4까지는 Stomp의 이름대로 텍스트 기반의 메시징만 지원했지만,

Stomp version 5부터는 Binary 메시지 전송도 지원한다고 한다. 즉, 이미지나 파일에 대한 전송도 지원한다는 것. 77ㅑ륵!

 

StompJS는 Client에서 이런 Stomp를 사용할 수 있도록 만들어놓은 라이브러리다.

Frontend 단에서 이러한 Stomp protocol을 쉽게 사용할 수 있다.


⛳️ (추가) HTTP 방법으로 실시간 통신 구현하기

위에서 잠깐 언급했던, WebSocket이 나오기 이전에는 어떻게 이러한 실시간 통신을 처리했을까? 에 대한 내용이다.

아래 세가지의 방법은 결국 모두 HTTP를 통해 통신하기 때문에, 요청/응답 Header가 모두 불필요하게 크다는 단점이 있다.

HTTP Polling

Client가 서버로 1초에 한 번, 10초에 한 번.. 이런 식으로 주기적인 요청을 날려 새로운 이벤트가 있는 지 확인한다.

Client와 Server 모두 구현이 쉽다는 장점이 있다. (유일한 장점인 듯..)

하지만 주기에 맞추어 요청을 날리는 것일 뿐이기 때문에 실시간성이 보장되지 않는다.

내가 메시지를 보내고 바로 답이 왔더라도, Client 요청 주기가 1분이라면 1분동안 응답을 받을 수 없다. 

그 반대로 응답이 30분 간 오지 않더라도 Client가 계속 주기적으로 요청을 보내기 때문에 Server 측의 부담이 크다. 

실시간성이 크게 중요하지 않다면, 괜찮은 방법이다. (근데 실시간성이 중요하지 않을리가?!!!!)

 

HTTP Long Polling

이름처럼 Polling과 닮아있다. Client가 Server로 요청을 보내는 것은 동일하다. 

하지만 이번에는 Client가 Server로 요청을 보내, 어떤 이벤트가 발생할 때까지 기다린다.

그리고 이벤트가 발생하면, 그 때 Client로 응답을 보낸다. 

응답을 받은 Client는 바로 다시 요청을 보내, Connection을 연결시킨다.

Polling에 비해서는 요청량이 줄어들어 Server의 부담이 줄어들지만, 만약 이벤트가 많이 발생한다면 

결국 주기적으로 요청을 보내는 Polling 방법과 큰 차이가 없게 된다.

또, 다수의 Client에게서 동시에 이벤트가 발생하게 되면, 다수의 Client가 Server에 접속을 시도하기 때문에 

결국 이 또한 Server의 부담이 커진다. 

예를들어, 갑자기 동시간대에 1000명의 유저가 막 채팅을 한다고 가정해보자.

Server에 1000개의 요청이 막 가게 되면서 Server에 엄청난 부하가 오게 될 것이다.

 

HTTP Streaming

Streaming 방식은, Client가 Server로 요청을 보내 Connection을 맺은 후, 

이벤트가 발생해도 Server는 이 Connection을 끊지 않는다. 

뭔가 여기까지는 오오..! 그러면 실시간 통신이 되는건가..! 싶은데, 그건 아니다.

Client에서 연결을 끊지 않고 유지하기에 Server는 계속해서 Client로 메시지를 보낼 수 있는 반면,

Client는 Streaming을 하면서 TCP Port로 읽기와 쓰기를 동시에 할 수 없기 때문에 더 이상의 요청을 할 수 없다.

Streaming 중 요청을 보내고 싶다면, TCP 이외의 다른 Port를 이용해야 한다는 문제점이 있다.

 


마치며

Socket..에 대해 이해하는 데 꽤나 오래 걸렸다. 하아악

최대한 내가 이해한대로 쉽게 풀어쓰려 하다보니.. 오래걸리기도 했고 정말 길고 긴 포스트가 되었다. <<ㅏ흑

Socket에 대해 찾아볼 때 정말 CS, Network에 대한 지식이 많이 필요한 것 같았다...

너무 전문 용어들이 많이 나오면 읽기 싫어지니까.. 뭉뚱그려 설명해 놓은 부분이 군데군데 있다.

그렇기 때문에.. 혹시라도 잘못된 부분이 있다면 언제든 피드백 주세요..!!!!!!!!!

하하하

 

 

 

https://mangkyu.tistory.com/48

 

[네트워크 프로그래밍] Http 프로그래밍과 Socket 프로그래밍 차이

일반적으로 단말기에서 필요로 하는 데이터들은 Server에서 관리합니다. 네트워크를 통해 서버로부터 데이터를 가져오기 위한 통신을 구현하기 위해서는 크게 Http 프로그래밍과 Socket 프로그래밍

mangkyu.tistory.com

 

https://recipes4dev.tistory.com/153

 

소켓 프로그래밍. (Socket Programming)

1. 소켓(Socket) 만약 네트워크와 관련된 프로젝트를 진행하면서, 사용자(User)의 관점이 아닌, 개발자(Developer)의 관점에서 네트워크를 다뤄본 경험이 있다면, "소켓(Socket)"이라는 용어가 아주 낯설

recipes4dev.tistory.com

https://tyrionlife.tistory.com/781

 

[네트워크] 소켓 프로그래밍이란(Socket Programming)

1. 소켓 프로그래밍 개요 □ 소켓의 의미 사전적으로 '구멍', '연결', '콘센트' 등의 의미 프로그램이 네트워크에서 데이터를 송수신할 수 있도록, '네트워크 환경에 연결할 수 있게 만들어진 연결

tyrionlife.tistory.com

https://velog.io/@guswns3371/WebSocket-and-Socket.IO

 

WebSocket and Socket.IO

webSocket 이전에는 실시간 통신을 위해 http request에 트릭을 사용하여 실시간인 것처럼 작동하게 하는 기술을 사용함http 프로토콜 자체가 클라이언트에서 서버로의 단방향 통신을 위해 만들어진

velog.io