WebSocket을 공부해보자

hwanse·2021년 9월 6일
0

HTTP

목록 보기
1/1

개요

이번에 토이 프로젝트를 진행하면서 Websocket을 활용하게 되었다. 간단한 채팅 기능을 개발하면서 어떤 이유에서 Websocket을 선택했고 Websocket을 공부한 내용을 정리해보려고 합니다


목차

  • Websocket이란?
    • Websocket 특징
  • Http, Websocket 비교
  • 양방향 통신을 위한 다른 방법들
    • Websocket의 등장
    • Websocket 활용시 이슈

Websocket이란?

웹소켓(WebSocket)은 사전상 자료의 내용을 참조하자면 다음과 같이 정의된다. 하나의 TCP 접속에 전이중 통신 채널을 제공하는 컴퓨터 통신 프로토콜이다.
전이중 통신: 클라이언트-서버 서로 쌍방이 송신할 수 있다는 것

그리고 이어서 다음과 같이 설명이 이어진다.

웹소켓은 HTTP와 구별된다. 두 프로토콜 모두 OSI 모델의 제7계층에 위치해 있으며 제4계층의 TCP에 의존한다. 웹소켓은 HTTP 포트 80과 443 위에 동작하도록 설계되었으며 HTTP 프록시 및 중간층을 지원하도록 설계되었으므로 HTTP 프로토콜과 호환이 된다. 호환을 달성하기 위해 웹소켓 핸드셰이크는 HTTP 업그레이드 헤더를 사용하여 HTTP 프로토콜에서 웹소켓 프로토콜로 변경한다.
웹소켓 프로토콜로 전환은 예를 들어 다음과 같은 Http 요청으로부터 시작되고 Upgrade 헤더와 함께 랜덤하게 생성된 키값을 서버에 보내고 서버는 이 키를 바탕으로 토큰을 생성한 뒤 클라이언트에 돌려준다.

클라이언트 요청

GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13
Origin: http://example.com

서버 응답

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=
Sec-WebSocket-Protocol: chat

이와 같은 형태로 웹소켓 핸드쉐이킹이 성공한 뒤 웹소켓 프로토콜로 변환되었을 때 TCP 소켓은 클라이언트와 서버가 데이터를 주고 받을 수 있도록 열린 상태를 유지한다. 여러 TCP 커넥션을 생성하지 않고 한번의 커넥션을 통해서 마치 여러 개의 커넥션을 맺는 것과 같은 효과를 내는 방식이다.
한 번의 커넥션을 통해 자유롭게 데이터를 주고 받을 수 있는 통신이므로 기존의 요청-응답 형태의 통신 방식보다 더 쉽고 효율적으로 데이터를 교환할 수 있다.
(단, Websocket 통신 할 서버가 웹 서버 뒤에 위치하여 구성되어 있는 형태일 경우 Websocket Updade 요청 헤더를 해당 서버에 전달하도록 웹 서버를 구성해야하는 주의점이 있다)

Websocket 특징

  • Http기반으로 Http통신의 문제점을 해결하기 위한 목표로 등장
  • 전 이중 통신(Full-duflex): 송신과 수신을 동시에 처리 가능
  • 실시간으로 업데이트되는 웹 어플리케이션에서 자주 사용됨
  • Http 요청을 그대로 사용하기 때문에 Http 규격인 CORS 적용, 인증 적용과 같은 과정들을 기존과 동일하게 가져감

사실 위 내용을 읽고 이해가 될 듯하면서도 아직까진 아리송한 것 같다. Websocket의 특징이 뭔지 정리하고 넘어가고 이어지는 내용들을 쭉 훑어보며 Websocket을 활용하기 전에는 어떤 기술들이 활용되었는지 알아보고 websocket이 왜 등장하게 되었는지를 알고 나면 이 기술을 좀 더 이해할 수 있을 것 같다.


Http, Websocket 비교

두 프로토콜 모두 Http 요청으로 시작하는 공통점을 가지고 있지만, 두 프로토콜은 다른 방식으로 동작한다.

HTTP

  • 여러 URL을 기반으로 Request-Response 형태로 통신하는 만큼 여러번의 커넥션이 발생
  • 동기적인 통신
  • 서버측에서 URI, Method, Headers 정보를 통해서 핸들러가 적절하게 라우팅 처리가 가능


    Websocket
  • 최초에 커넥션을 수립하기 위한 하나의 URL만 있고 모든 메세지는 동일한 TCP 커넥션을 통해서 전달
  • 비동기(asynchronous)통신, 이벤트 기반(event-driven) 아키텍처 모델
  • 클라이언트-서버 사이에 주고받는 메세지에 임의로 의미를 부여해서 처리, 이러한 문제를 해결하기 위해서 STOMP 같은 메세징 프로토콜을 사용하여 보완 가능

실시간 통신을 위한 다른 방법들

Http통신 규격 자체가 클라이언트에서 서버로 단방향 통신을 위해 만들어진 방법인데, websocket이 등장하기 이전에는 실시간 통신을 위해 아래와 같은 형태로 실시간인 것 처럼 트릭을 걸어 작동하게하는 방식들이 활용되었다고 한다.

1. Polling

클라이언트가 Http Request를 서버로 계속해서 보내고 이벤트 내용을 전달받는 방식이다. 클라이언트 입장에서는 지속적으로 서버에 요청을 지속적으로 보내고 응답을 받는 방식으로 구현이 가능하기 때문에 기술적으로 구현이 쉽고 간단하나 여러 단점들이 따라오는 기법이다.

특징

  • 구현이 쉽다
  • 사용자가 많아질수록 서버가 받는 요청도 그만큼 급증한다
  • Http 커넥션 연결 수립이 자주 일어나 해당 과정 자체가 네트워크 비용이 많은 방식이다
  • 유저가 아무런 행위를 하지 않아도 서버는 불필요하게 리소스를 소모한다
  • 사실 실시간처럼 빠른 응답을 기대하기 어렵다

2. Long Polling

클라이언트가 서버로 Http 요청을 보낸 뒤 서버가 클라이언트의 요청에 대한 이벤트를 처리했을 때 서버는 그 순간 응답 메세지를 보내고 클라이언트 입장에서는 응답이 올 때까지 대기 상태로 있다가 응답을 받는다. 클라이언트는 또다시 곧바로 다시 서버에서 요청을 보내 서버의 다음 이벤트를 대기하고 응답을 받고 이러한 과정을 반복하는 방식이다. 이전에 Polling 기법과 차이점은 클라이언트는 서버에서의 이벤트가 발생하고 처리 여부와는 상관없이 계속 요청을 보내고 데이터의 변동이 있을 때 업데이트를 진행하는 방식이고, Long Polling은 이벤트가 발생하고 처리될 때까지 대기 상태를 유지하기 때문에 과정상 차이점이 있다.

특징

  • 서버에서 이벤트가 발생할때 까지 대기하여 커넥션을 유지한다
  • 위와 같은 연결 과정의 차이로 Polling 방식보다는 서버에 덜 요청을 보내 서버의 부담이 줄어든다
  • 그러나 서버측에서 이벤트가 자주 발생하여 클라이언트가 요청을 보내는 주기가 짧아진다면 폴링과 큰 차이가 없어진다
  • Long Polling방식 또한 다수의 클라이언트가 동시에 이벤트가 발생된다면 서버는 그만큼 다수의 클라이언트의 요청을 받아야하기 때문에 서버의 부담이 급증하게 된다

3. Http Streaming

클라이언트가 Http 요청을 서버로 보내고 서버는 응답을 끊임없이 흘려 내보내는 기법이다. Polling, Long Polling 같은 기법들과 다르게 요청을 받으면 커넥션을 끊지 않고 하나의 Http 커넥션을 통해서 서버가 데이터를 보내는 방식이다. Long Polling과 비교하면 서버에서 데이터를 보내고 나서 Http 요청을 또 보내지 않고 연결이 유지되고 있으니 어떻게 보면 Websocket이랑도 비슷한 것 같다. 그러나 차이점이 존재한다고 한다.
Http Streaming 기법은 하나의 TCP 포트로 읽기와 쓰기 연산을 동시에 할 수 없다는 제약이 있다. 결론적으로 서버에서 클라이언트로 데이터를 내보낼 수 있으나 클라이언트에서 서버로 메세지를 보내려면 다른 방식으로 우회하는 기법이 필요하다고 한다. 예를 들어 채팅 기능을 구현한다고 가정했을 때 사용자가 입력한 메세지 전송을 TCP가 아닌 포트를 통해 받도록 처리하도록 하는 방식이 존재한다고 한다. 그러나 개인적으로 이처럼 우회하는 방식이 있다 하더라도 문제를 해결하기 위해서 또 다른 문제를 만들어내는 것 같다는 생각이 든다.


결론적으로 Websocket과 다른 방식의 통신 방식들은 실시간 통신이라 하기에는 제약이 있었고 정리하자면 다음과 같다.

- Http 통신 자체의 통신규약으로 인하여 실시간 상호 작용이 어렵다.(서버에 요청을 보내고 응답을 받으면 연결이 끊어지는 특성)
- Polling, Long Polling과 같은 실시간 통신인 것 처럼 속이는 기법들이 있지만 서비스가 커지고 사용자가 많아질수록 서버의 부담이 커지고 성능이 저하되는 원인이 되어 본래 의도였던 실시간 통신이 어려워진다


Websocket의 등장

Websocket은 Http 기반으로 하면서 Http의 문제점을 해결하는 것을 목표로 나온 기술이며 전이중 통신이 가능하다. Socket 커넥션을 유지하는 상태이기 때문에 양방향 통신을 이용하여 데이터를 전송할 수 있다.
기존 TCP Socket 연결과의 다른 점은 Websocket은 최초 접속을 Http 요청을 통해서 Handshaking이 이루어진다는 점이다. 또한 TCP Socket 연결에서는 바이트 스트림을 사용하지만 Websocket을 통해 전달되는 텍스트들은 UTF-8 포맷으로 전달된다. 이제 처음에 봤던 Websocket 특징을 다시 한번 살펴보자.

  • Stateful: 클라이언트와 한번 연결이 되면 계속 같은 커넥션을 사용하여 통신하기 때문에 Http 통신에서 커넥션을 맺을 때 발생하는 불필요한 네트워크 비용을 줄일 수 있다.
  • Http 요청을 그대로 사용하기 때문에 기존 Http의 규격인 CORS 적용, 인증 등의 과정을 동일하게 가져갈수 있다.

Websocket 활용시 이슈

Websocket은 이전에 Http 통신의 단점들을 극복하기 위해서 등장했지만 단점이 없는 것은 아니다.

  • Stateful한 만큼 서버와 클라이언트 연결을 계속 유지하므로, 비정상적으로 연결이 끊어졌을 때에 대한 핸들링이 필요하다
  • 서버, 클라이언트 간에 socket 연결하는 것 자체 또한 서버의 리소스를 많이 소모한다. 예를들어 트래픽을 많이 받는 서버일 경우에는 CPU 부담이 커질 수 있다.

결론

이번에 토이 프로젝트로 간단한 채팅 기능을 주제로 진행하려 했었고 이때 Web 환경에서 실시간성 채팅 기능을 구현하기 위해서 어떤 기술을 활용하면 좋을지 고민했었고 Websocket을 공부하게 된 계기가 되었다. 실시간성 기능 사항을 만들 때 Websocket을 활용할 수 있다는 말을 익히 들어왔으나 왜 이 기술을 활용하면 좋을지 공부하려고 노력했다. 공부하면서 Websocket에 대해서 좀 더 이해할 수 있었고 채팅 기능 개발에 활용하기로 했다. 왜 Websocket을 활용하게 되었는지 이유는 다음과 같다.

  • 채팅 기능은 실시간 통신이 요구된다
  • 채팅 기능에는 텍스트 채팅뿐만 아니라 음성 채팅도 포함되어 있었고 이때 활용할 WebRTC에서 Signalling 서버를 구성할때 Websocket의 특성을 적극적으로 활용하는 것이 좋다고 생각이 들었다
  • Websocket을 활용하면 STOMP와 같은 서브 프로토콜을 활용하는 방안도 있고 서버 개발시 유용해진다


참고 자료

profile
만사가 귀찮은 ISFP가 쓰는 학습 블로그

1개의 댓글

comment-user-thumbnail
2023년 12월 20일

감사합니다 잘 정리해주셔서 덕분에 공부하고 갑니다!

답글 달기