Spring WebSocket은 Spring 프레임워크에서 제공하는 모듈로, 웹 소켓 통신을 지원한다.
GET /spring-websocket-portfolio/portfolio HTTP/1.1
Host: localhost:8080
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: Uc9l9TMkWGbHFD2qnFHltg==
Sec-WebSocket-Protocol: v10.stomp, v11.stomp
Sec-WebSocket-Version: 13
Origin: http://localhost:8080
HTTP/1.1 프로토콜에서
Upgrade헤더는 클라이언트와 서버간의 프로토콜 전환을 요청하는 데 사용된다.
Upgrade 헤더: websocket으로 설정되어 있으며, 이는 클라이언트가 WebSocket 연결을 원하고 있다는 신호이다.
Connection 헤더: Upgrade로 설정되어 있습니다. 이는 연결이 업그레이드되어 WebSocket으로 전환될 것임을 나타낸다.
WebSocket 특정 헤더들 :
Sec-WebSocket-Key: WebSocket 통신에서 보안을 강화하기 위한 키이다.Sec-WebSocket-Protocol: 클라이언트가 지원하는 WebSocket 서브프로토콜을 지정한다.v10.stomp, v11.stomp로 지정되어있다.Sec-WebSocket-Version: WebSocket 프로토콜의 버전을 나타낸다. 여기에서 13으로 설정되어있다.HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: 1qVdfYHU9hPOl4JYYNXF623Gzn0=
Sec-WebSocket-Protocol: v10.stomp
HTTP/1.1 101 Switching Protocols: WebSocket으로의 전환을 의미하는 상태 코드로, 서버가 클라이언트의 WebSocket 요청을 성공적으로 수락했음을 의미한다.Upgrade: websocket 및 Connection: Upgrade: 클라이언트와 서버 간의 프로토콜을 변경하기 위해 사용되는 헤더이다. 클라이언트가 Upgrade: websocket 및 Connection: Upgrade 헤더를 포함하여 WebSocket으로 업그레이드를 요청하면, 서버는 이를 수락하여 이러한 헤더를 응답에 포함시킨다.< WebSocketConfig >
/**
* WebSocket 구성 클래스.
*/
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
/**
* 메시지 브로커를 설정
* @param config MessageBrokerRegistry 객체
*/
@Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
// 클라이언트에게 메시지 전달을 위한 브로커를 활성화 : 구독 (Subscribe)
registry.enableSimpleBroker("/sub");
// 클라이언트가 메시지를 서버로 전송할 때의 Prefix를 설정 : 구독에 대한 메세지 (publish)
registry.setApplicationDestinationPrefixes("/pub");
}
/**
* STOMP 엔드포인트를 등록
* @param registry StompEndpointRegistry 객체
*/
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
// STOMP 프로토콜을 사용하는 클라이언트의 웹소켓 엔드포인트를 등록
registry.addEndpoint("/ws")
.setAllowedOriginPatterns("*")
.withSockJS();
}
}
@EnableWebSocketMessageBroker: WebSocket 메시징을 사용하겠다는 것을 알려줌.
WebSocketMessageBrokerConfigurer: 이 인터페이스는 WebSocket 구성을 위한 메서드를 제공한다.
configureMessageBroker(MessageBrokerRegistry registry): 이 메서드는 메시지 브로커를 설정한다. 메시지 브로커는 서버와 클라이언트 간의 메시지 전달을 조정한다.
registry.enableSimpleBroker("/sub"): 클라이언트에게 메시지를 전달하기 위한 브로커를 활성화하고, 클라이언트가 /sub로 시작하는 주제를 구독할 수 있도록 한다.
registry.setApplicationDestinationPrefixes("/pub"): 클라이언트가 서버로 메시지를 전송할 때의 접두사를 설정한다. 클라이언트는 이를 사용하여 /pub로 시작하는 주제로 메시지를 발생할 수 있다.
registerStompEndpoints(StompEndpointRegistry registry): 메서드는 STOMP(간단한 텍스트 지향 메시지 프로토콜) 엔드포인트를 등록한다. registry.addEndpoint("/ws")는 클라이언트가 웹소켓에 연결할 수 있는 엔드포인트를 설정한다. .setAllowedOriginPatterns("*")는 모든 origin에서의 연결을 허용한다. withSockJS()는 SockJS(웹 브라우저의 WebSocket을 지원하지 않는 경우를 고려한 대체 수단)를 사용하여 웹소켓을 지원한다.
< WebSocketHandler >
/**
* WebSocketHandler 클래스는 TextWebSocketHandler를 확장하여 WebSocket 연결을 처리하는 핸들러
*/
public class WebSocketHandler extends TextWebSocketHandler {
/**
* 클라이언트가 WebSocket 연결을 성공적으로 맺었을 때 호출
* @param session 연결된 WebSocket 세션
* @throws Exception 예외가 발생할 경우
*/
@Override
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
System.out.println("WebSocket connection established with session ID: " + session.getId());
}
/**
* 클라이언트로부터 텍스트 메시지를 받았을 때 호출
* @param session 연결된 WebSocket 세션
* @param message 수신된 텍스트 메시지
* @throws Exception 예외가 발생할 경우
*/
@Override
protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
String payload = message.getPayload();
System.out.println("Received message from client: " + payload);
// 클라이언트에게 응답을 보냅니다.
session.sendMessage(new TextMessage("Server received your message: " + payload));
}
/**
* 클라이언트가 WebSocket 연결을 종료했을 때 호출
* @param session 연결된 WebSocket 세션
* @param status 연결 종료 상태
* @throws Exception 예외가 발생할 경우
*/
@Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
System.out.println("WebSocket connection closed with session ID: " + session.getId());
}
}
WebSocket 핸들러는 클라이언트와 서버 간의 연결 상태를 관리하고, 연결이 성공적으로 맺어졌을 때와 끊어졌을 때의 동작을 처리한다. 또한 클라이언트로부터 수신된 메시지를 처리하고, 필요한 셩우 서버에서 클라이언트로 메시지를 전송하는 역할을 수행한다.