배경
프로젝트 주제를 팀원들과 정하면서 무엇을 해볼까 고민하던 중 오픈 채팅에 대한 이야기도 나오게 되었습니다. 팀원중 한분이 웹소켓을 써야 하지 않냐고 하셔서 어떤 것인지 궁금해 찾아보게 되었습니다. 웹소켓은 어떤것이고 왜 오픈채팅 같은 것을 사용할 때 필요한 것일까요?
내용
예를들어 상대방과 같이 이용할 수 있는 체스 게임을 만든다고 해봅시다. 일반적인 http를 이용해서 구현을 할 수도 있겠지만 이렇게 구현을 하게 된다면 상대방이 체스를 옮길 때마다 새로고침을 통해 정보를 받아와야 합니다. 일반적으로 http는 비연결성인 특성을 가지고 있기 때문이죠. 새로고침 하지 않고도 실시간으로 정보를 받아올 수 있게 하는 것이 바로 웹소켓입니다. 게임, 채팅, 실시간 주식 거래 사이트 등에서 많이 사용하고 있는 기술이죠.
그럼 무조건 웹소켓을 사용해야 하느냐? 그건 아닙니다. http에서도 실시간성을 보장하는 기법이 존재하긴 합니다. polling, long polling, streaming 등이 있지만 그래도 웹소켓을 이용할 수 있는 환경이면 웹소켓을 이용하는 것이 일반적입니다. 이 이유에 대해 조금씩 알아보죠.
<HTTP vs 웹소켓>
HTTP와 웹소켓의 가장 큰 차이는 커넥션을 어떻게 하느냐 입니다. http의 경우 클라이언트가 요청을 보낼 때 연결을 맺고 응답을 받으면 연결을 끊어버리는 비연결성입니다. 반면 웹소켓은 연결을 맺고 나면 어느 한쪽에서 연결을 끊으라는 요청을 보내기 전까지 연결을 계속 유지하게 됩니다. 이렇게 함으로써 매 연결마다 발생하는 비용을 줄일 수 있는거죠. 예를들어 http로 연결을 맺을 경우 3way, 4way hand-shake를 계속 반복하게 될텐데 매번 이런 과정을 거칠 필요가 없어지게 됩니다.
또 하나의 차이점은 통신 방식에 잇습니다. http는 요청과 응답이 한 쌍을 이루는 구조입니다. 어떤 것을 얻기 위해서는 계속해서 요청을 해야하죠. 하지만 웹소켓은 연결이 유지되고 있는 상태이기 때문에 상대가 보내주는 걸 받기만 해도 되는겁니다.
http요청과 응답을 하기 위해서는 매번 왼쪽과 같은 데이터를 넣어주어야 하죠. 이는 비용이 생각보다 큽니다. 하지만 웹소켓의 경우 처음에 연결할 때만 http를 통해 연결을 맺고 이후 연결이 이뤄진 후에는 오른쪽 아래와 같은 필요한 데이터만 주고받게 됩니다.
<지원 현황>
웹소켓은 모든 환경에서 사용이 가능할까요? 그렇지는 않습니다. 웹소켓을 제공하지 않는 것들도 있으니 잘 구분해서 사용해야 합니다.
위처럼 지원되지 않는 환경에서 사용할 수는 있습니다. 대안으로 polling이나 streaming을 지원하면 이걸 사용하는 방법도 생각을 해봐야겠죠.
<웹 소켓 동작 방식>
앞서 웹소켓의 처음 연결은 http를 통해 연결이 된다고 했습니다.
클라이언트가 요청하기 위해서는 아래와 같은 정보들이 필요하죠. 각 헤더에 대한 정보를 간단하게 말씀드리면 Upgrade의 경우 현재 클라이언트, 서버, 전송 프로토콜 연결에서 다른 프로토콜로 업그레이드 또는 변경하기 위해 설정하는 것입니다. Upgrade에 websocket을 적어주게 되면 다음부터는 프로토콜을 웹소켓으로 변경하겠다는 뜻이 되는거죠. 다음으로 Upgrade 헤더 필드가 명시된 경우 송신자는 반드시 Upgrade 옵션을 지정한 Connection 헤더 필드도 전송 해주어야 합니다. 그리고 Sec-WebSocket-Key 헤더 필드가 있습니다. 이를 통해 클라이언트와 서버간 신원을 인증하게 됩니다.
다음으로 서버에서 응답을 받게 되면 다음과 같이 헤더 필드가 구성되어 있습니다.
Sec-WebSocket-Accept는 요청에서 보내진 Sec-WebSocket-Key 값을 이용하여 계산된 값을 넘겨줍니다. 이 정보가 다르게 되면 당연히 연결이 안되겠죠?
이렇게 연결이 완료되면 이제 http로 이런 요청을 보낼 필요 없이 message라는 단위를 이용해 통신을 하게 됩니다. 이때 메시지는 frame이라는 데이터 단위로 이루어져 있습니다. frame은 작은 헤더 + payload로 구성이 되어 있습니다. 참고로 웹소켓 통신에 사용되는 데이터는 UTF8인코딩만 지원 가능합니다.
웹소켓 연결을 위해서는 별도의 포트는 필요하지 않으면 기존 포트(http-80, https-443)을 사용하게 됩니다. 메시지 교환가능한 데이터는 텍스트와 바이너리 타입 뿐인것도 알고 계시면 좋을 듯 합니다.
<웹소켓의 한계>
웹소켓의 장점과 특징에 대해 알아봤으니 한계에 대해 알아봐야겠죠? 웹소켓은 문자열들을 주고 받고 있게 해줄 수 있을 뿐 그이상의 일은 하지 않습니다. 문자열의 해독은 온전히 어플리케이션에 맡기게 되는거죠. 따라서 형식이 http처럼 딱 정해진게 없기 때문에 어플리케이션에서 해석하기 힘든 경우가 굉장히 많습니다. 때문에 주고받는 메시지의 형태를 약속하는 것이 거의 필수적입니다. 이를 보완하기 위해 STOMP라는 것이 있는데 이는 다음 시간이 알아보도록 하겠습니다.
참고
'네트워크' 카테고리의 다른 글
Apache와 Nginx (2) | 2024.12.20 |
---|---|
RabbitMQ와 Kafka 차이에 대한 간단 설명 (0) | 2024.12.18 |
네트워크와 인터넷 (0) | 2024.12.12 |