일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
- 알고리즘
- Spring #Java #Spring Boot #싱글톤
- 15552
- 1110
- Spring #Java #Spring Boot
- 백준
- 11053
- sequelize
- Java #코딩테스트
- python
- Spring #Spring Boot #Java
- boj
- 24479
- kakaocloudschool
- Java #오븐시계 #백준
- 2447
- 9020
- Spring #Java #Spring Boot #@BeforeEach #@AfterEach
- Spring
- 11054
- 파이썬
- node
- Java #백준 #코딩테스트
- 카카오클라우드스쿨
- java
- 코딩테스트
- SpringTokenizer
- kakaocloud
- 카카오 클라우드 스쿨
- 7568
- Today
- Total
YoungSoo
[WebSocket] 명령과 조회를 분리하는 CQRS로 개발하기 - 2 본문
WebSocket에 대해 알아보자!
웹소켓이란, TCP 접속에 전이중 통신 채널(양방향 통신 채널)을 제공하는 컴퓨터 통신 프로토콜이다. 이를 사용하면 서버와 브라우저 간에 연결된 상태로 데이터를 교환할 수 있습니다. 데이터는 패킷(packet)의 형태로 전달이 되고, HTTP 요청을 하지 않고 양방향 통신이 이루어집니다.
- 패킷이란?
- 네트워크 통신에서 데이터를 전송하는 최소 단위
WebSocket 패킷은 헤더(Header)와 페이로드(Payload)로 구성됩니다.
헤더에는 패킷의 메타데이터와 제어 정보, 패킷의 길이, 압축 여부, 메시지 타입 등의 정보가 헤더에 포함될 수 있습니다.
페이로드는 실제 전송되는 메시지, 이벤트 데이터, 상태 정보 등이 페이로드에 포함됩니다.
왜 WebSocket을 사용해?
WebSocket은 전이중 통신 채널을 제공해서 실시간성을 보장할 수가 있습니다. WebSocket을 기반으로 실시간으로 채팅 서비스를 개발하려고 합니다. 하지만 WebSocket은 연결을 유지해야 하기에 서버의 자원 부하가 증가할 수 있습니다. 이러한 서버 부하를 해결해 주기 위해서는 메시지 큐를 도입해 비동기로 메시지 처리를 분산하고 빠르게 처리할 수 있습니다.
HTTP를 통해서는 실시간성 통신이 불가능한가?
아닙니다. HTTP를 통해서도 실시간성을 보장하는 기술이 존재합니다!
Polling, Long Polling, Streaming와 같은 기술이 있습니다. 하지만 HTTP는 기본적으로 요청/응답 방식으로 동작하기 때문에 실시간성으로 동작하는 애플리케이션엔 WebSocket이 적절하다고 생각을 했습니다.
WebSocket의 동작방식 - 핸드 쉐이킹
STOMP(Simple Text Oriented Messaging Protocol)
메시지 브로커을 활용하여 쉽게 메시지를 주고받을 수 있는 프로토콜
- Pub - Sub(발행 - 구독) 방식으로 발신자가 메시지를 발행하면 수신자가 그것을 수신하는 메시징 패러다임
- 메시지 중개인: 발신자의 메시지를 받아와서 수신자들에게 메시지를 전달하는 것
WebSocket 위에 함께 사용할 수 있는 하위(서브) 프로토콜
STOMP를 왜 같이 사용해?
WebSocket만 사용한다면 키-값의 형태로 주고받아지지만 STOMP를 같이 사용하게 되면 커맨드, 헤더, 바디의 형태처럼 구조화된 메시지를 전송하고, 메시지 큐와 통합이 가능하게 됩니다. 또한 연결 주소마다 새로 핸들러를 구현하고 설정해 줄 필요가 없습니다.
동작흐름
발신자가 구독자에게 메시지를 보낼 때 메시지의 가공이나 처리가 필요하다면 MessageHandler를 통해 메시지를 처리하고 MessageBroker를 통해 다시 응답해 줄 수도 있고, 필요하지 않다면 바로 구독자에게 전송도 가능합니다.
실습
아래 링크를 통해 Spring Boot에서 WebSocket과 STOMP를 통해 실습을 진행해 주었습니다.
https://spring.io/guides/gs/messaging-stomp-websocket/
Getting Started | Using WebSocket to build an interactive web application
In Spring’s approach to working with STOMP messaging, STOMP messages can be routed to @Controller classes. For example, the GreetingController (from src/main/java/com/example/messagingstompwebsocket/GreetingController.java) is mapped to handle messages t
spring.io
의존성 추가
implementation 'org.webjars:webjars-locator-core'
implementation 'org.webjars:sockjs-client:1.0.2'
implementation 'org.webjars:stomp-websocket:2.3.3'
implementation 'org.webjars:bootstrap:3.3.7'
implementation 'org.webjars:jquery:3.1.1-1'
Message 클래스 생성
public class HelloMessage {
private String name;
public HelloMessage() {
}
public HelloMessage(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public class Greeting {
private String content;
public Greeting() {
}
public Greeting(String content) {
this.content = content;
}
public String getContent() {
return content;
}
}
컨트롤러 생성
@Controller
public class GreetingController {
@MessageMapping("/hello")
@SendTo("/topic/greetings")
public Greeting greeting(HelloMessage message) throws Exception {
Thread.sleep(1000); // simulated delay
return new Greeting("Hello, " + HtmlUtils.htmlEscape(message.getName()) + "!");
}
}
STOMP 메시징을 위한 Config 구성
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
@Override
public void configureMessageBroker(MessageBrokerRegistry config) {
config.enableSimpleBroker("/topic");
config.setApplicationDestinationPrefixes("/app");
}
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/gs-guide-websocket").withSockJS();
}
}
마무리
이렇게 간단하게 입력된 메시지가 화면에 출력되는 것을 확인할 수 있었습니다. 처음에는 @MessageMapping를 사용한다면 "Rest API와 비슷하게 동작하는 것이 아닐까?"라는 생각이 들었습니다. 하지만 @MessageMapping은 STOMP 기반의 메시징 엔드포인트를 처리하기 위한 어노테이션이고, WebSocket 연결을 통해 클라이언트로부터 수신된 메시지를 처리하는 핸들러 메서드에 적용됩니다. 그래서 이 어노테이션을 사용하면 실시간 메시징을 위해 사용되어 동작합니다. 다음 게시물은 실제 채팅 서비스를 구현하는 과정을 게시하려고 합니다!!
'프로젝트' 카테고리의 다른 글
[WebSocket] 명령과 조회를 분리하는 CQRS로 개발하기 - 4 (0) | 2023.07.29 |
---|---|
[WebSocket] 명령과 조회를 분리하는 CQRS로 개발하기 - 3 (0) | 2023.07.18 |
[CQRS] 명령과 조회를 분리하는 CQRS로 개발하기 - 1 (0) | 2023.07.04 |
[Furry_Friend_Chat] 채팅 서비스 요구사항 분석 및 설계 (0) | 2023.07.03 |
[Spring Cloud Gateway] CORS 문제 해결하기 (0) | 2023.06.20 |