JAVA
Spring의 WebSocket
D_Helloper
2023. 6. 8. 21:44
WebSocket
- 기존 단방향 HTTP 프로토콜과 호환되어 양방향 통신을 제공하기 위해 개발된 프로토콜
- TCP/IP 레이어(4계층)를 사용하는 Socket과 달리 HTTP 레이어(7계층)에서 동작 80 포트를 사용하므로 방화벽에 제약이 없으며 WebSocket이라고 불림
- HTTP 프로토콜을 사용하여 연결을 한 뒤, 자체적인 WebSocket 프로토콜을 활용하여 통신 진행
- 실시간 양방향 통신을 위해 사용
HTTP와 WebSocket의 차이
출처 : https://kbj96.tistory.com/46
- HTTP는 Response 이전에 Request가 반드시 존재해야 함
- 하지만 이럴 경우, 채팅과 같은 경우에는 서버에 주기적으로 Request를 전송하여 메시지가 왔는지 확인해야 함 → 매우 비효율적
- WebSocket은 양방향 통신이기 때문에 연결 이후에는 자유로이 통신 가능
Spring Websocket
- 스프링에서 기본적으로 내장되어 있는 웹소켓
사용법
- 의존성 추가(Gradle)
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-websocket'
}
- WebSocket 엔드포인트 생성
@Component
@ServerEndpoint("/websocket")
public class MyWebSocketEndpoint {
@OnOpen
public void onOpen(Session session) {
// 연결이 열릴 때 실행되는 로직
}
@OnMessage
public void onMessage(String message, Session session) {
// 클라이언트로부터 메시지를 받을 때 실행되는 로직
}
@OnClose
public void onClose(Session session) {
// 연결이 닫힐 때 실행되는 로직
}
@OnError
public void onError(Throwable error) {
// 에러 발생 시 실행되는 로직
}
}
- WebSocket 구성
- Spring의 구성 파일에서 WebSocket을 활성화 해야 함
- @EnableWebSocket 어노테이션 사용하여 클래스를 만듦
- registerWebScoketHandler() 메서드를 오버라이드하여 WebSocket 핸들러 등록
@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {
@Autowired
private MyWebSocketEndpoint myWebSocketEndpoint;
@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
registry.addHandler(myWebSocketEndpoint, "/websocket")
.setAllowedOrigins("*");
}
}
- 위에서 만든 MySwbSocketEndpoint 클래스를 Autowired를 통해 주입받음
- WebSocketHandlerRegistry를 사용하여 WebSocket 핸들러 등록
- 위 코드는 setAllowedOrigins(”*”); 를 통해 모든 origin으로부터의 요청을 허용하도록 되어 있음
STOMP(Simple Text Oriented Messaging Protocol)
- Spring Framework에서 지원하는 메시징 프로토콜
- 브로커, 목적지, 구독, 발행의 개념을 포함
Broker(브로커)
- STOMP 메시지를 중계하고 클라이언트 간의 통신을 관리하는 중앙 시스템
- STOMP Broker는 메시지를 발행(Publish)하고, 메시지를 구독(Subscribe)하는 클라이언트에게 메시지를 전달
Destination(목적지)
- 메시지가 발행되거나 구독되는 대상 주제(topic)를 의미
- 클라이언트는 특정 주제에 대한 구독 또는 발행 요청 가능
Subscribe(구독)
- 클라이언트가 특정 주제(topic)에 대한 메시지를 수신하기 위해 구독 요청을 보내는 동작
- 클라이언트는 특정 주제를 구독하면 해당 주제로 발행되는 메시지를 수신할 수 있음
Publish(발행)
- 클라이언트가 특정 주제에 메시지를 발행하는 동작
- 발행된 메시지는 해당 주제를 구독한 클라이언트에게 전달
사용법
- 의존성 추가(Gradle)
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-websocket'
implementation 'org.springframework.boot:spring-boot-starter-messaging'
}
- WebSocket 엔드포인트 및 STOMP 핸들러 생성
- 연결을 처리할 엔드포인트와 핸들러를 생성
- 핸들러는 StompSessionHandlerAdapter를 상속받아 구현
- 핸들러의 메시지를 수신하거나 전송하는 로직 구현
@Component
public class MyStompHandler extends StompSessionHandlerAdapter {
@Override
public void afterConnected(StompSession session, StompHeaders connectedHeaders) {
// 연결이 성공한 후 실행되는 로직
}
@Override
public void handleFrame(StompHeaders headers, Object payload) {
// 클라이언트로부터 STOMP 메시지를 수신할 때 실행되는 로직
}
}
- WebSocket 구성
- @EnableWebSocketMessageBroker 어노테이션을 사용하여 구성 클래스 생성
- configureMessageBroker() 메서드를 오버라이드 하여 메시지 브로커 설정
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
@Autowired
private MyStompHandler myStompHandler;
@Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
registry.enableSimpleBroker("/topic"); // 구독 대상 주제 설정
registry.setApplicationDestinationPrefixes("/app"); // 클라이언트에서 메시지를 전송할 경로 설정
}
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/websocket") // WebSocket 엔드포인트 등록
.setAllowedOrigins("*") // 모든 origin 허용 (보안 상황에 맞게 수정)
.withSockJS(); // SockJS 지원 (브라우저의 WebSocket 지원 여부에 따라 자동 선택)
}
@Override
public void configureClientInboundChannel(ChannelRegistration registration) {
registration.interceptors(new MyChannelInterceptor()); // 채널 인터셉터 등록 (선택 사항)
}
@Override
public void configureClientOutboundChannel(ChannelRegistration registration) {
registration.interceptors(new MyChannelInterceptor()); // 채널 인터셉터 등록 (선택 사항)
}
}
Spring WebSocket과 STOMP 차이
Spring WebSocket
- WebSocket 프로토콜을 기반으로 한 실시간 통신을 구현하기 위한 기술
- 웹 브라우저와 서버 간의 양방향 통신을 지원하며, 실시간 데이터 전송이 필요한 애플리케이션에 적합
- 간단한 API를 제공하며, 개발자는 직접 WebSocket을 처리하는 로직을 구현해야 함
- WebSocket 연결을 설정하고, 클라이언트로부터 메시지를 수신하거나 메시지를 전송하는 등의 로직을 직접 구현해야 함
STOMP (Simple Text Oriented Messaging Protocol)
- STOMP는 메시징 프로토콜로, WebSocket을 기반으로 한 실시간 통신을 더 쉽게 구현하기 위한 프로토콜
- STOMP는 클라이언트와 서버 간의 메시지를 주고받기 위한 프레임워크
- STOMP는 구독-발행 모델을 제공하여 클라이언트가 특정 주제에 대한 메시지를 구독하고, 서버는 해당 주제에 메시지를 발행할 수 있음
- STOMP는 헤더, 몸체, 명령어 등의 구조로 메시지를 정의하고, 간단한 명령어를 사용하여 메시지를 전송
- Spring에서는 STOMP를 사용하기 위해 spring-messaging 모듈을 제공하며, @MessageMapping 어노테이션과 같은 편리한 기능을 제공
STOMP가 Spring에서 기본적으로 제공하는 WebSocket보다 더 쉽고 간편하게 구조적으로 소켓을 구현할 수 있음