forDevLife
[TIL]11/10 - 웹소켓 & 스프링 본문
우아한 Tech의 10분 테크톡을 보고 정리한 내용입니다.
출처 : https://www.youtube.com/watch?v=rvss-_t6gzg
웹 소켓은 언제 사용될까?
- 실시간 성을 보장하는 서비스
- 게임, 채팅, 실시간 주식 거래 사이트에서 사용된다.
- 전 이중성 통신
- 웹 소켓 사용 없이는, 웹 게임 또는 채팅 등을 할 때 계속 새로고침을 해줘서 상대방의 정보를 받아와야 한다.
HTTP vs 웹 소켓
- HTTP에서도 실시간성을 보장하는 기법이 존재
- Polling, Long Polling, Streaming 등을 이용해서 서버와의 연결을 끊지 않고 계속 데이터를 주고 받을 수 있다.
HTTP
- 비 연결성
- 매번 연결 맺고 끊는 과정에서 비용 발생 (HandShake)
- (요청 - 응답)이 한 쌍을 이루는 구조 -> 벽에다 치는 탁구에 비유
웹 소켓
- 연결 지향
- 한번 연결 맺은 뒤 유지
- 양방향 통신 -> 일반 스마트폰에 비유
데이터 측면에서 비유
- HTTP는 매번 Request / Response 헤더들의 양이 방대하다.
- 웹소켓도 처음 handshake 과정에서는 http 프로토콜을 이용하기 때문에 비슷한 양을 주고 받는다.
- 하지만 연결 후에는, 적은 양의 데이터로 통신이 가능하다. 비용을 많이 줄일 수 있다.
웹 소켓 지원 현황
- 대부분의 브라우저에서 사용 가능하다.
- 하지만 일부 과거 버전에서 사용이 불가능한 경우가 있다.
- 이를 지원하지 않는 환경에는 SockJs, Socket.io 라이브러리를 통해 사용이 가능하다.
- 스프링에서 어떻게 웹 소켓을 이용하는지 알아보자.
Spring-WebSocket
1. WebSocketConfig
- SocketTextHandler()
- 스프링에서 웹 소켓을 사용하려면, 클라이언트가 보내오는 통신을 처리 할 핸들러가 필요하다.
- 웹 소켓이 연결될 때 핸드쉐이크 할 주소를 인자로 넣어주면 된다. 여기에서는 "/user"가 주소이다. - setAllowedOrigins
- cors(Cross-Origin Resource Sharing - 교차(다른) 출처 리소스 공유) 설정
- 와일드카드(*)로 설정해 두면, 출처(origin)에 상관 없이 리소스를 공유하겠다는 설정이다.
- cors 관련 : https://evan-moon.github.io/2020/05/21/about-cors/ - withSockJS()
- SockJS 사용 위한 설정(웹 소켓 지원 안하는 브라우저에서도 가능하게 하기위한 설정)
2. SocketTextHandler() : 직접 구현
- 앞서 addHandler로 전달되는 custom socketHandler에 대한 구현이다.
- 기본적으로 text, binary handler를 제공하며, 이를 구현해주면 된다.
- 오버라이딩 한 메서드를 보면, WebSocketSession을 인자로 받아온다. 웹소켓이 연결될 때 생성되는 연결정보를 담는 객체이다.
- 이 세션들을 컬렉션으로 담아서 관리한다. 커넥션 연결 시 컬렉션에 담고, 해제 시 컬렉션에서 제거한다.
- handleTextMessage 메서드에서 보이듯, Set에 있는 세션에 대해 공통 처리를 할 수 있다.
Spring Message?
- 스프링 부트에서는 스프링 웹 소켓 이외에 의존 관계에서 Spring Message도 같이 딸려오는 것을 알 수 있다.
- 이를 위해서 STOMP에 대해서 알아보자.
STOMP - Simple Text Oriented Messaging Protocol
- 메시지 브로커를 활용하여 쉽게 메시지를 주고 받을 수 있는 프로토콜
- Pub-sub(발행-구독) : 발신자가 메시지를 발행하면 수신자가 그것을 수신하는 메시징 패러다임
- 메시지 브로커 : 발신자의 메시지를 받아와서 처리 후 수신자들에게 메시지를 전달하는 어떤 것 - 웹소켓 위에 얹어 사용할 수 있는 하위(서브) 프로토콜. 스프링이 이걸 지원한다.
- 왜 굳이 하나를 더 얹어서 사용해야 할까?
- Stomp는 프레임 단위의 프로토콜이다(커맨드, 헤더, 바디로 이루어져 있음)
- 웹 소켓 정보에 추가 정보, 기능을 부여할 수 있다.
통신 흐름
- 서버에서 SimpleAnnotationMethod를 통해 구독자가 요청한 내용을 가공 / 처리한 후 보내줄 수 있다.
위에서는 /app을 요청할 때 메시지가 가공될 것이다. - 또는 SimpleBroker를 통해 처리를 안하고 응답도 가능하다.
위에서는 /topic을 요청할 때 가공 없이 처리될 것이다.
Spring - WebSocketMessageBroker
- enableSimpleBroker : 내장 브로커를 사용하여 처리된다.
+ queue : 1대 1 송신, topic : 1대 다(브로드캐스팅) 송신용으로 해당 prefix를 활용한다. - setApplicationDestinationPrefixes : 핸들러로 라우팅 되기를 원하는 prefix를 넣어준다.
아래와 같은 핸들러로 전달된다. - addEndPoint()
- 웹 소켓 연결 주소 설정
- 이전처럼 Handler 하나하나 추가할 필요 없이 controller 하나로 처리가 가능하다.
Message Handler
- /hello로 오는 메시지에 대해서 처리를 진행하는 컨트롤러이다.
- 처리 후 /topic/greeting이라는 경로로 이동된다. 이는 앞서 설정한 simpleBroker이다.
STOMP 장점
- 하위 프로토콜, 컨벤션을 따로 정의할 필요 없다. STOMP에서 정의를 해준다.
- 연결 주소마다 새로 핸들러를 구현하고 설정할 필요 없다.
- @Controller를 통해 기존의 방식으로 활용 가능하다.
- 외부 Message Queue를 사용할 수 있다.(RabbitMQ, 카프카 등)
- Spring Security를 사용할 수 있다.
'각종 회고' 카테고리의 다른 글
[WIL] 2022년 1주차 회고 (1) | 2022.01.09 |
---|---|
[TIL]11/12 - Forward Proxy, Reverse Proxy, Load Balancer (0) | 2021.11.12 |
[TIL]9/15 - AOP (0) | 2021.09.29 |
[TIL]9/15(5일차) - WEB2 : OAuth 2.0 (0) | 2021.09.15 |
[TIL]9/14(4일차) - Spring Boot Security + OAuth (0) | 2021.09.14 |
Comments