Spring WebSocket

정환우·2022년 3월 29일
1

스프링

목록 보기
4/9
post-thumbnail

졸업프로젝트에서 스프링을 이용한 웹소켓을 사용할 일이 있어 여러 레퍼런스를 며칠동안 찾아봤는데, 이해가 될 듯 하면서도 이해가 안된다.

MVC도 제대로 이해 못했는데 웹소켓이라니.. 그래도 머리 박치기로 한번 정리해보자.

WebSocket이란?

웹소켓이란, TCP 접속에 전이중 통신 채널(양방향 통신 채널)을 제공하는 컴퓨터 통신 프로토콜이다.

RFC 6455 명세서에 정의된 프로토콜인 웹소켓(WebSocket)을 사용하면 서버와 브라우저 간 연결을 유지한 상태로 데이터를 교환할 수 있다. 이때 데이터는 ‘패킷(packet)’ 형태로 전달되며, 전송은 커넥션 중단과 추가 HTTP 요청 없이 양방향으로 이뤄진다.

이런 특징 때문에 웹소켓은 온라인 게임이나 주식 트레이딩 시스템같이 데이터 교환이 지속적으로 이뤄져야 하는 서비스에 아주 적합하다.

연결 구조

그렇다면 웹소켓이 연결되는 구조는 어떻게 되는지 한번 확인해보자.

HTTP 통신으로 handshake를 한 후에 ws로 프로토콜을 변환하여 웹소켓 프레임을 통해 데이터를 전송한다. 전이중 통신 채널을 사용하므로 요청과 응답을 구분하지 않는다. 종료시에는 close handshake를 보내 종료하게 된다.

클라이언트의 요청과 서버의 응답을 한번 살펴보자.

클라이언트 요청

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

이렇게 Connection 과 Upgrade를 통해 HTTP 사용 방식을 WebSocket으로 변경하자는 내용을 보낸다.

서버는 그럼 Sec-WebSocket-Protocol 에 있는 프로토콜 중 하나를 골라서 사용하게 된다.

서버 응답

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

이제 다음 통신부터는 웹소켓으로 통신이 가능하게 된다. chat 프로토콜을 선택한 것을 볼 수 있다.

웹소켓은 브라우저에서 지원해줘야 사용이 가능한데, 이렇게 지원하지 않는 브라우저가 더러 있다. 이러한 브라우저들을 웹소켓 통신하는 것처럼 지원해주는게 우리가 사용할 sockJS의 역할이다.

SockJS

WebSocket API를 사용하는 어플리케이션에서 브라우저가 WebSocket을 지원하지 않는 경우가 있을 수 있다.

이 때, 코드를 변경할 필요 없이 런타임에 WebSocket을 HTTP Streaming이나 Long-Polling과 같은 HTTP 기반의 다른 기술로 전환해 다시 연결을 시도해주는 WebSocket Emulation이 바로 SockJS 이다.

일단은 이정도면 알고 넘어가면 될 것 같고, 자세한 내용은 공식 문서를 참고하면 도움이 될 것 같다.

STOMP

STOMP는 Simple Text Oriented Messaging Protocol의 약자로, 양방향 네트워크 프로토콜을 기반으로 동작한다. 웹소켓은 두 가지 유형의 메세지를 정의하고 있지만 그 내용까지는 정의하고 있지 않은데, STOMP 프로토콜은 이 웹소켓 위에서 동작하는 프로토콜이며 클라이언트와 서버가 전송할 메세지의 유형, 형식, 내용들을 정의하는 매커니즘이다.

메세지 헤더에 값을 줄 수 있어 헤더 기반 값으로 인증 처리를 구현할 수 있고, 정의한 규칙을 잘 지키면 여러 언어 및 플랫폼간 메세지 상호 운영을 할 수 있다.

그리고 또 중요한 점은, Publisher-Subscribe 매커니즘을 제공한다. 기본적으로 스프링 애플리케이션이 STOMP Broker로 동작을 하게 되며, RabbitMQActiveMQ 같은 외부 메세징 시스템을 Broker로 사용할 수 있도록 지원하고 있다.

이 경우에 외부 브로커는 스프링과 클라이언트 사이의 매개체로 동작하게 되며, 스프링과 브로커는 TCP 커넥션을 유지한다.

스프링이 브로커에 메세지를 전달하고, 브로커가 클라이언트에게 메세지를 전달하는 구조이다. 위와 같은 구조를 사용하면 스프링은 HTTP 기반의 보안 설정과 공통된 검증 등을 적용할 수 있다고 한다.

STOMP 구현체에서 문자열 구문에 따라 직접 의미를 부여하도록 하기 위해 Destination 정보를 불분명하게 정의하였다고 한다. 하지만 일반적으로 /topic 문자열로 시작하는 구문은 One-to-Many로 관계로 pub/sub 을 의미하고, /queue 문자열로 시작하는 구문은 One-to-One 메세지 교환을 의미한다고 한다.

이제야 조금 이해가 될랑 말랑 한다..
샘플 코드 써보면서 조금 더 분석해봐야겠다

Reference

개발하는 고라니

고승빈님 velog

기록은 재산이다 블로그

Spring Docs

profile
Hongik CE

0개의 댓글