[Spring] 웹소켓으로 양방향 통신 기능 구현

윤성철·2025년 7월 20일

Back-End

목록 보기
22/22
post-thumbnail

서론

오픈카톡방을 많이 사용하고 있는데, 이를 가능하게 해주는 WebSocket을 공부하게 되었다. 추후 실시간 공매도 거래나 관련한 실시간 통신에 대해 업무를 맡을 수도 있으니..

본론

웹 환경에서 우리는 HTTP 프로토콜을 통해 요청과 응답의 구조로 서비스를 이용하고 있다. 그렇다면 HTTP 통신을 사용하고 있는데, 왜 또다른 Socket 통신을 사용할까?

HTTP 통신의 특징

  • 비연결성 : 커넥션을 맺고 요청 이후 응답을 받으면 연결을 끊는다.
  • 무상태성 : 서버가 클라이언트의 상태를 가지고 있지 않는다.
  • 단방향 : 클라이언트는 서버에 요청을 하고, 서버로부터 응답을 받을 수만 있다.

위 3가지 특징을 살펴보면, HTTP 통신은 커넥션을 맺었다가 응답 이후 끊기를 반복하고, 양방향이 아닌 서버로부터 단방향으로 응답을 받는 통신이기 때문에 양방향으로 실시간 통신에 적합하지 않음을 알 수 있다.

즉, 우리가 자주 사용하는 카카오톡에서 대화방이나 혹은 주식 거래할 때 매도, 매수 거래를 채결하는 실시간성 서비스에는 HTTP 통신이 적합하지 않음을 알 수 있다.

WebSocket이란

클라이언트와 서버 간에 지속적인 양방향 통신을 가능하게 하는 프로토콜

  • Full-Duplex : 클라이언트와 서버가 양방향으로 실시간 데이터를 주고받을 수 있다.
  • 지속 연결 : 한번 연결하면 끊기지 않고 커넥션이 유지된다.
  • 기반 : TCP 위에서 동작한다.
  • 경량 : HTTP보다 헤더가 작고 가볍다. 즉, 속도가 빠르다.

⚡ 채팅과 같이 양방향 실시간 통신에 자주 사용되는 통신 프로토콜로 이해하면 된다.

SpringWebSocket 구현

Springboot에서 WebSocket 라이브러리를 지원해주기때문에 사용하면된다. 간단하게 입출력을 위해 화면은 html, js로 구성했다.

build.gradle

의존성 부분에서 눈여겨봐야할 부분은 stomp-websocket부분이다.

STOMP란?

텍스트 메시지 형식 정의를 위한 애플리케이션 레벨 메시지 프로토콜

WebSocket은 OSI 7계층 중 애플리케이션 레벨에서 동작하는데, 해당 계층위에 binary, text로 메시지를 주고받을 수 있도록 하는 프로토콜이다.

갑자기 무슨 프로토콜 설명이야라고 생각했는데, Spring Websocket은 통신을 담당하고, STOMP는 그 위에서 메시지 구조와 규칙을 담당하는 이른바 상호보완 관계라서 알고있어야하는 개념이다.

STOMP 구조

  • HTTP Request, Response보다 매우매우 간단하게 경량화돼있는 것을 볼 수 있다.

우리가 흔히 최신기술로 알고있는 메시지큐(Kafka, RabbitMQ)를 사용해서 메시지를 라우팅하고, pub/sub형태로 통신할 수 있게 해주는 것이 SMTOP이다.

WebSocket config

  • configureMessageBroker 메서드에 작성한 주석을 통해 알 수 있듯, /topic 경로에 발행한 메세지는 구독자들에게 전달 되고, app 경로에 발행한 메세지는 가공을 거쳐 메세지 브로커로 전달되어 궁극적으로 구독자들에게 전달된다.

/topic과 /app 라우팅 과정을 도식화하면 다음과 같다.

결국 /app으로 전송한 데이터는 가공되어서 /topic으로 라우팅되어서 메세지 브로커에 도착한다. 이후 메세지 브로커는 consumer들에게 데이터를 전달하는 구조로 이해하면된다.

controller

@MessageMapping 어노테이션은 우리가 RestController를 구현하면서 사용했던 @RequestMapping과 유사하다고 느꼈다.
해당 어노테이션은 /app/hello 경로로 들어온 메세지를 greeting 메서드에서 가공하여 /topic/greetings 경로로 라우팅하는 컨트롤러 코드다.

위 그림에서도 봐서 이해했겠지만, 간략하게 재설명하자면 /app은 수신지점이라고 생각하고, /topic은 송신 지점이라고 생각하면 좀 더 이해가 쉬울거 같다.

실행 화면

connect를 통해 먼저 tcp 연결을 수립하고, 이름을 작성 후 send를 누르면,

이렇게 실시간으로 전달되는 것을 확인할 수 있다. HTTP 통신이었다면, ajax 비동기 호출을 하거나 새로고침을 했어야했을텐데 허허

결론

간단하게나마 Spring WebSocket으로 실시간 통신을 구현해봤다.

중요한건 연결을 맺어서 통신을 하는게 맞지만, 그사이에 spring에 내장돼있는 메시지 브로커가 pub/sub형태로 구독자들에게 메세지를 전달해주는 사실이다.

추후 채팅서버를 만들어보고자 한다.

출처

https://growth-coder.tistory.com/157
https://adjh54.tistory.com/573
https://www.youtube.com/watch?v=rvss-_t6gzg&ab_channel=%EC%9A%B0%EC%95%84%ED%95%9C%ED%85%8C%ED%81%AC
https://spring.io/guides/gs/messaging-stomp-websocket

profile
내 기억보단 내가 작성한 기록을 보자..

0개의 댓글