STOMP (Simple Text Oriented Messaging Protocol)
http 프로토콜을 사용하는 포트 위에서 ws://를 사용한다.
여지껏 써온 request, response 이외에도 웹소켓에서는
Subscribe, Broadcast 라는 개념이 필요하다.
기존에는 요청(request)하면 돌려주는(response) 형식,
요청이 능동적이었지만, 웹소켓은 반대이다. 응답이 능동적인.
웹소켓은 그냥 뿌리는 것.
어떠한 사람이 구독(Subscribe)을 하면 그 사람에게 방송(Broadcast)을 해주면 되는 것.
websocket 의존성 추가
WebSocketHandler 클래스 생성
컨트롤러 같은 역할. 컨트롤러는 아니다.
@Component : 스프링이 인식해야 하기에 붙여준다.
TextWebSocketHandler를 상속하고
네가지를 불러온다.
채팅을 하는 클라이언트들끼리 채팅을 주고 받는게 아니라 서버에게 보내면 그 서버가 가져다 뿌리는 것이다. 그러한 방식.
그래서 handleMessage가 중요하다.
전달받고 있는 WebSocketSession은 HttpSession과는 전혀 관계가 없다.
위 둘의 세션은 철저히 분리되어 있음을 알 것.
누군가 접속을 하면 우리는 그 접속한 사람을 기억하고 있어야 한다.
현재 접속한 사람의 명단이라 생각하면 된다.
WebSocketHandler 클래스에 있는 SESSIONS에 getId 키를 넣고 그 값을 session으로 한다.
들어왔으면 나갈 때는 명부에서 지워주어야 하기에 remove.
SESSIONS : 사용자
사용자에게 뿌린다.
HandleMessage를 지우고 HandleTextMessage로 다시 가져오기
HomeController 생성. 맵핑해주고
WebSocketConfig 생성. WebSocketConfigurer 구현해주고 @Configuration 어노테이션 붙여주기. 인터셉터 할 때와 같네.
@Configuration
어노테이션은 Spring IOC에게 해당 클래스는 @Bean
구성 클래스임을 명시해주는 것이다.
에러가 떴다. 확인해보니 WebSocketHandler 클래스에서 붙여두었던 @Component
를 지우지 않아 생긴 에러였다.
@Bean
어노테이션과 Component
어노테이션 둘다 Spring(IOC) Container에 Bean을 등록하도록 하는 메타데이터를 기입하는 어노테이션이다. 그렇다면 왜 두개나 만들어 놓았을까? 둘의 용도가 다르기 때문이다.
@Bean
어노테이션의 경우 개발자가 직접 제어가 불가능한 외부 라이브러리 등을 Bean
으로 만들려 할 때 사용이 된다.
@Component
의 경우 개발자가 직접 작성한 Class를 Bean으로 등록하기 위한 어노테이션이다.
@Component
를 사용한 Bean의 의존성 주입은 @AutoWired
어노테이션을 이용하여 할 수 있다. 아래와 같이 Student가 Pencil에 대한 의존성을 가지고 있는 경우 @AutoWired
어노테이션을 이용하여 의존성을 자동으로 주입할 수 있다. 이때 당연히 Pencil도 @Component
어노테이션을 가지고 있어야 한다. 그래야만 IOC Container 에 Bean
으로 등록이 되기 때문이다.
@Bean
사용법
요약하자면, @Component
는 개발자가 직접 작성한 Class를 Bean으로 만드는 것이고, @Bean
은 개발자가 작성한 Method를 통해 반환되는 객체를 Bean
으로 만드는 것이다. 또한 각자의 용도가 정해져 있으므로 정해진 곳에서만 사용 가능하며, 다른 곳에서 사용하려 한다면 Compile에러를 내뱉는다.
simple/home/index.html 생성
static/simple/resources/stylesheets/index.css 생성
body {
background-color: rgb(23, 32, 42);
}
body > .app {
top: 50%;
left: 50%;
width: 100%;
height: 100%;
max-width: 22.5rem;
max-height: 35rem;
background-color: rgb(234, 236, 238);
color: rgb(23, 32, 42);
display: flex;
flex-direction: column;
justify-content: flex-start;
overflow: hidden;
position: absolute;
transform: translate(-50%, -50%);
}
body > .app > .chat-container {
align-items: flex-start;
display: flex;
flex: 1;
flex-direction: column;
justify-content: flex-start;
overflow: hidden auto;
padding: 0.75rem 0.75rem 0 0.75rem;
}
body > .app > .chat-container::-webkit-scrollbar {
width: 0.5rem;
background-color: transparent;
}
body > .app > .chat-container::-webkit-scrollbar-thumb {
background-color: rgb(171, 178, 185);
border-radius: 1rem;
}
body > .app > .chat-container > .chat {
background-color: rgb(174, 214, 241);
border-radius: 0.5rem;
margin-bottom: 0.5rem;
padding: 0.5rem 1rem;
text-align: justify;
}
body > .app > .message-form {
align-items: stretch;
display: flex;
flex-direction: row;
justify-content: flex-start;
padding: 0.75rem;
}
body > .app > .message-form > .message-container {
align-items: stretch;
box-sizing: border-box;
display: flex;
flex: 1;
flex-direction: column;
justify-content: flex-start;
margin-right: 0.375rem;
}
body > .app > .message-form > .message-container > .message-input {
background-color: rgb(255, 255, 255);
border: 0.0625rem solid rgb(213, 216, 220);
border-radius: 0.5rem;
box-sizing: border-box;
color: rgb(0, 0, 0);
font: inherit;
outline: none;
padding: 0.5rem 1rem;
}
body > .app > .message-form > .send-button {
appearance: none;
background-color: rgb(23, 32, 42);
border: none;
border-radius: 0.5rem;
color: rgb(234, 236, 238);
cursor: pointer;
font: inherit;
padding: 0.5rem 1rem;
}
body > .app > .message-form > .send-button:hover {
filter: brightness(105%);
}
body > .app > .message-form > .send-button:active {
filter: brightness(95%);
}
index.js 생성
http://localhost:8080/simple/ 주소로 들어가보면