출처: https://blog.naver.com/eztcpcom/220070508655
GET /chat HTTP/1.1
Host:server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Origin:http://example.com
Sec-WebSocket-Protocol: v10.stomp, v11.stomp, my-team-custom
Sec-WebSocket-Version: 13
Connection: Upgrade
: HTTP 사용 방식을 변경하자.Upgrade : websocket
: WebSocket을 사용하자.Sec-WebSocket-Protocol: xxx, yyy, zzz
: WebSocket을 쓰면서 이 중에서 protocol을 골라서 쓰자.Sec-WebSocket-Key
: 보안을 위한 요청 키.HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
101 Switching Protocols
: Handshake 요청 내용을 기반으로 다음부터 WebSocket으로 통신할 수 있다.Sec-WebSocket-Accept
: 보안을 위한 응답 키 - base64.encode(Sec-WebSocket-Key.concat(GUID))
자주 + 많은 양의 + 지연이 짧아야 하는 통신
을 할 수록 WebSocket이 적합하다.SockJS Client는 서버의 기본 정보를 얻기 위해 "GET /info"를 호출하는데, 이는 서버가 WebSocket을 지원하는지, 전송 과정에서 Cookies 지원이 필요한지 여부 그리고 CORS를 위한 Origin 정보 등의 정보를 응답으로 전달받는다.
pub /sub란 메시지를 공급하는 주체와 소비하는 주체를 분리하여 제공하는 메시징 방법이다.
예를 들면 우체통(topic)이 있으면 집배원(publisher)이 신문을 우체통에 배달하는 액션이 있고,
우체통에 신문이 배달되는 것을 기다렸다가 빼서 보는 구독자(subscriber)의 액션이 있다.
여기서 구독자는 여러명이 될 수 있다.
출처: https://medium.com/frientrip/pub-sub-잘-알고-쓰자-de9dc1b9f739
COMMAND
header1:value1
header2:value2
Body^@
SUBSCRIBE
destination: /subscribe/chat/room/5
SEND
content-type: application/json
destination: /publish/chat
{"chatRoomId": 5, "type": "MESSAGE", "writer": "clientB"}
@Configuration
@EnableWebSocketMessageBroker
public class WebSockConfig implements WebSocketMessageBrokerConfigurer {
@Override
public void configureMessageBroker(MessageBrokerRegistry config) {
config.enableSimpleBroker("/sub");
config.setApplicationDestinationPrefixes("/pub");
}
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/ws-stomp").setAllowedOriginPatterns("*")
.withSockJS();
}
}
setApplicationDestinationPrefixes
: client에서 SEND
요청을 처리한다./topic
, /queue
가 주로 등장하는데 여기서는 이해를 돕기 위해 /publish
로 지정하였다./topic
: 암시적으로 1:N 전파를 의미한다./queue
: 암시적으로 1:1 전파를 의미한다./pub
로 시작하도록 설정/sub
로 시작하도록 설정/ws-stomp
로 설정enableSimpleBroker
: 해당 경로로 SimpleBroker
를 등록한다. SimpleBroker
는 해당하는 경로를 SUBSCRIBE
하는 client에게 메시지를 전달하는 간단한 작업을 수행한다.enableStompBrokerRelay
: SimpleBroker
의 기능과 외부 message broker(RabbitMQ
, ActiveMQ
등)에 메시지를 전달하는 기능을 가지고 있다.@RequiredArgsConstructor
@Controller
public class ChatController {
private final SimpMessageSendingOperations messagingTemplate;
@MessageMapping("/chat/message")
public void message(ChatMessage message) {
if(ChatMessage.MessageType.ENTER.equals(message.getType()))
message.setMessage(message.getSender() + "님이 입장하셨습니다.");
messagingTemplate.convertAndSend("/sub/chat/room/" + message.getRoomId(), message);
}
}
SimpleMessagingTemplate
: @EnableWebSocketMessageBroker
를 통해서 등록되는 bean이다. 특정 Broker로 메시지를 전달한다.
@MessageMapping
: Client가 SEND
를 할 수 있는 경로다. StompWebSocketConfig
에서 등록한 applicationDestinationPrefixes
와 @MessageMapping
의 경로가 합쳐진다.(/pub/chat/message
)
/sub/chat/{roomId}
는 채팅룸을 구분하는 값으로 Topic
의 역할SimpAnnotationMethod : @MessageMapping
등 client의 SEND
를 받아서 처리한다.
SimpleBroker : client의 정보를 메모리 상에 들고 있으며, client로 메시지를 내보낸다.
channel : 3종류의 channel이 등장한다
WebSocketMessageBrokerConfigurer
를 통해 interceptor, taskExecutor를 설정할 수 있다.WebSocketMessageBrokerConfigurer
를 통해 interceptor, taskExecutor를 설정할 수 있다.SimpAnnotationMetho
는 SimpleBroker
의 존재를 직접 알지 못해도 메시지를 전달할 수 있다(결합도를 낮춤)참조 :https://dev-gorany.tistory.com/m/224
https://www.daddyprogrammer.org/post/4731/spring-websocket-chatting-server-redis-pub-sub/