카테고리 없음

웹소켓, STOMP에 대해

2025. 2. 23. 13:38
목차
  1. Http, WebSocket
  2. 웹소켓 프로토콜은 http에 비해가볍다라는 뜻
  3. 웹소켓은 최초 연결을 맺을 때 HTTP메시지를 통해 연결요청을 한다??
  4. WebSocket Handshake
  5. 웹소켓의 인증처리
  6. Polling, SSE에 대해
  7. 순수 웹소켓으로 구현
  8. STOMP
  9. 스톰프 동작
  10. 스톰프 인증은 언제
  11. 스톰프를 프론트
  12. Redis pub/sub

채팅서버에 대해 정리하기 위해 글을 적었습니다

Http, WebSocket

http프로토콜은 서버로 요청을 하고 서버가 주는 응답을 기다리는 단방향 구조입니다
웹소켓은 클라이언트가 서버에게 메시지를 보낼수도있고 받을수도있다 양방향 통신
서버가 요청을안해도 클라이언트에게 먼저보낼수도있는것이다

웹소켓 프로토콜은 http에 비해가볍다라는 뜻

HTTP: 매 요청마다 헤더(Header)를 포함해야 하며, 기본적으로 수십수백 바이트의 헤더를 포함함.
WebSocket: 초기 핸드셰이크 후에는 헤더 크기가 매우 작아짐(보통 2
10바이트).
더해서 HTTP는 Stateless이다 그래서 요청마다 HTTP는 세션을 유지하기 위해 쿠키나 세션을 정보가 추가적으로 들어가지만 웹소켓은 그렇지 않다
불필요한 TCP 핸드셰이크를 반복하지 않기도 해서 가볍다라는 표현을 쓰는 것 같다

서버에서 사용자와 연결을 맺고 사용자에 대한 정보를 메모리에 가지고 있어야 한다. 메모리 중요!!! 휘발가능
프로토콜이 달라서 ws://을 사용 프로토콜 매우중요!!
그런데 코드보면은 ws://을 사용안하는경우있음 stomp라는 웹소켓에서 좀 더 발전된 기술에서는 명시적으로 ws://프로토콜을 사용하지않고 http url 패턴을 사용하지만 내부적으로는 ws:// 프로토콜이 사용된다

웹소켓은 최초 연결을 맺을 때 HTTP메시지를 통해 연결요청을 한다??

최초 연결시에는 HTTP프로토콜이지만 그 이후로는 웹소켓 프로토콜을 사용한다.
이것을 웹소켓 핸드쉐이크라고 부르기도 한다

GET /chat HTTP/1.1
Host: example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Version: 13

WebSocket Handshake

  1. 클라이언트 → 서버: HTTP 요청으로 WebSocket 업그레이드 요청

  2. 서버 → 클라이언트: HTTP 101 Switching Protocols 응답

  3. TCP 연결을 유지(HTTP는 매번 새로운 TCP연결)하고, 이후부터 WebSocket 프로토콜 사용

    초기 connect시에는 http요청메시지를 포함하여 보낼수 있습니다. 이를 핸드셰이크과정이라고 부르는데, 이 핸드셰이크가 끝나면 바로 ws프로토콜로 전환됩니다. 그래서, 이를 두고 http프로토콜을 통한 connect라고 보기는 부적절하지만 활용은 한다.
    정리하자면 초기 연결시에는 http요청을 활용하되, 결국은 ws프로토콜을 통해 연결이 맺어진다 보면되겠습니다. 초기에 http요청을 활용하기 때문에, header에 토큰등을 담아서 인증처리 등을 수행할수 있습니다.

웹소켓의 인증처리

중요 : 웹소켓도 최초 한번의 연결시 http헤더를 통해 token과 같은 인증 정보를 보낼 수 있고, 이때에 이를 통해 인증처리를 할 수 있음.

Polling, SSE에 대해

웹소켓말고 Polling, SSE도 있는데 알아보자

순수 웹소켓으로 구현

구현시에는 제일 중요한거는 순수웹소켓은 서버메모리를 사용한다는 것이다

  1. 웹소켓관련 Config정의 WebSocketConfigurer에서 커스텀할거 가져와서 오버라이드

  2. 핸들러 정의해주고 등록하기 - 핸들러란 웹소켓 연결이 들어오면 어찌처리할지 이런거를 정의하는거

    @Configuration
    @EnableWebSocket
    @RequiredArgsConstructor
    public class WebSocketConfig implements WebSocketConfigurer {
    
     private final SimpleWebSocketHandler simpleWebSocketHandler;
    
    
    
@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
    // connect url로 websocket연결 요청이 들어오면, 핸들러 클래스가 처리 핵심은 연결요청!!!
    registry.addHandler(simpleWebSocketHandler, "/connect")
        // cors예외 securityconfig에서의 cors예외는 http요청에 대한 예외, 따라서 websocket 프로토콜에 대한 요청에 대해서는 별도의 cors설정 필요.
        // securityconfig에서도 connect는 예외처리해줘야함
        .setAllowedOrigins("http://localhost:3000");


}

}


```java
@Component
@Slf4j
public class SimpleWebSocketHandler extends TextWebSocketHandler {

    // 연결된 세션 관리 : 스레드 safe한 자료구조
    private final Set<WebSocketSession> sessions = ConcurrentHashMap.newKeySet();
    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        // session의 아이피 브라우저 등등 정보가 들어있다
        sessions.add(session);
        log.info("Connected : {}", session.getId());

    }


    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        String payload = message.getPayload();
        log.info("Received Message : {}", payload);
        for(WebSocketSession s : sessions){
            if(s.isOpen()){ // Set에 담겨있는 연결된 모두에게 메시지를 보내겠다 (일반 웹소켓가지고는 방이나 이런 웹소켓코드는 짜기 힘들다)
                s.sendMessage(new TextMessage(payload));
            }
        }
    }

    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
        sessions.remove(session);
        log.info("Disconnected");
    }
}

직접 세션을 관리해야하는 문제. 채팅방이라는 것을 구현한다면 조금 더 복잡하게 될 것 그래서 STOMP를 사용

STOMP

ws위에서 동작하는 메시징 프로토콜
ws중요한게 여전히 누구에게 메시지 보낼지 연결되어있는정보는 서버메모리에 저장되어있다 (stomp도 서버 메모리에 저장이 중요)
단순한 방식을 가지고는 1번 채팅방에 묶여있는데 다른채팅방에 묶여있는경우 그룹핑되면은 순수웹소켓 가지고 구현하면은 코드가 굉장히 복잡해진다
이를위해 stomp라는 ws위에서 동작하는 기술이 나옴 stomp는 ws기반으로 동작하지만 중간에 브로커가 있다
브로커의 역할은 그룹핑 하는거 도와준다 클아이언트가 1번방 구독할래 하면은 브로커가 전부 다 매칭시켜준다
Ws고 stomp건 간에 분산환경에서는 어렵다 stomp도 그룹핑인데 하나의 서버메모리내에서 이루어지기때문이다
룸을 stomp에서는 topic이라고 부른다
웹소켓과 스톰프 차이는 토픽이라는곳에 메시지를 발행하고 해당 토픽을 구독해서 클라이언트가 받아간다는것이다

스톰프 동작

  1. connect
  2. 클라가 메시지 발행시에 어떤 룸(토픽)에 할건지 정하고
  3. 브로커라는 녀석이 특정 토픽에 메시지 발행
  4. 토픽을 구독한 대상자들에게 메시지 전달

웹소켓은 직접 세션정보를 관리했는데 세션관리를 서버에서 알아서해주는 편의를 제공해줌
직접 자료구조 사용해서 세션관리한거 스톰프에서는 안사용해도됨
웹소켓에서는 연결요청을 할 때 ws://으로 웹소켓 프로토콜인데 스톰프도 근간은 ws프로토콜인데 http요청 프로토콜로도 보낼 수 있다
허용만 해주는거임 SockJs라이브러리 사용하면 ws프로토콜이 아닌 http프로토콜로 연결을 시도할 수 있다

스톰프 인증은 언제

스톰프는 connect이후로 계속 통신하는경우 토큰을 가졌는지 인증을 해야한다
핸드쉐이크 후에 통신은 별개니까 보안을 여기서 해야하는 것이다

스톰프를 프론트

sockJs를 사용하면서 connect, subscribe, publish를 구현한다 HTTP프로토콜을 사용하지 않아서 endPoint를 RestController로 구현하지않는다 라는것을 명심.
프론트와 백엔드에서 중요한것은 세션관리 페이지이동, 나가기 버튼 누르는 경우 disocnnect를 잘 호출하기.

Redis pub/sub

Redis를 브로커로 이용하는것이다 여기서 말하는 브로커는 stomp에서 브로커가있는데
멀티서버 환경에서는 웹소켓연결은 서버에서 세션을 관리하다보니 공유저장소가 필요한데 이것을 Redis로 사용하는것이다

응용한 코드는 따로 기록할려고 한다.

  1. Http, WebSocket
  2. 웹소켓 프로토콜은 http에 비해가볍다라는 뜻
  3. 웹소켓은 최초 연결을 맺을 때 HTTP메시지를 통해 연결요청을 한다??
  4. WebSocket Handshake
  5. 웹소켓의 인증처리
  6. Polling, SSE에 대해
  7. 순수 웹소켓으로 구현
  8. STOMP
  9. 스톰프 동작
  10. 스톰프 인증은 언제
  11. 스톰프를 프론트
  12. Redis pub/sub
cwangg897
cwangg897
cwangg897
wang's tech blog
cwangg897
전체
오늘
어제
  • 분류 전체보기 (43)
    • Kusinsa (1)
    • 자바 (0)
    • 스프링 (1)
    • 용어정리 (1)
    • Delivery (15)
    • Delivery - WIL (3)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • r

최근 댓글

최근 글

hELLO · Designed By 정상우.
cwangg897
웹소켓, STOMP에 대해
상단으로

티스토리툴바

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.