안녕하세요, 코린이의 코딩 학습기 채니 입니다.
개인 포스팅용으로 내용에 오류 및 잘못된 정보가 있을 수 있습니다.
Spring-WebSocket
pom.xml
#14. websocket 관련 의존 추가
<!-- #14 websocket 관련 의존 추가 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-websocket</artifactId>
<version>${org.springframework-version}</version>
</dependency>
servlet-context.xml
#14.1 echoHandler 등록
<!-- #14.1 echoHandler 등록 -->
<websocket:handlers>
<websocket:mapping handler="echoHandler" path="/echo"/>
</websocket:handlers>
security-context.xml
<intercept-url pattern="/ws/**" access="permitAll"/>
<intercept-url pattern="/echo/**" access="permitAll"/>
Handler
EchoHandler
@Component
@Slf4j
public class EchoHandler extends TextWebSocketHandler{
List<WebSocketSession> sessionList = new CopyOnWriteArrayList<>(); // 멀티쓰레딩 환경에서 사용하는 리스트(쓰기 작업용을 별도로 복사해서 만들어놓음 -> 동기화 성능저하를 방지해줌)
/**
* @OnOpen
*/
@Override
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
sessionList.add(session);
log.debug("[add 현재 세션수 {}] {}", sessionList.size(), session.getId());
}
/**
* @OnClose
*/
@Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
sessionList.remove(session);
log.debug("[remove 현재 세션수 {}] {}", sessionList.size(), session.getId());
}
/**
* @OnMessage
*/
@Override
protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
log.debug("[message] {} : {}", session.getId(), message.getPayload());
for(WebSocketSession sess : sessionList) {
sess.sendMessage(new TextMessage(session.getId() + ":" + message));
}
}
}
Controller
WebsocketController
@Controller
@Slf4j
@RequestMapping("/ws")
public class WebsocketController {
@GetMapping("/ws.do")
public void ws() {}
}
ws.jsp
<jsp:include page="/WEB-INF/views/common/header.jsp">
<jsp:param name="title" value="Websocket | Sockjs" />
</jsp:include>
<div class="input-group mb-3">
<input type="text" id="message" class="form-control"
placeholder="Message">
<div class="input-group-append" style="padding: 0px;">
<button id="sendBtn" class="btn btn-outline-secondary" type="button">Send</button>
</div>
</div>
<div>
<ul class="list-group list-group-flush" id="data"></ul>
</div>
<script>
const ws = new WebSocket(`ws://\${location.host}${pageContext.request.contextPath}/echo`);
ws.addEventListener('open', (e) => console.log("open : ", e));
ws.addEventListener('error', (e) => console.log("error : ", e));
ws.addEventListener('close', (e) => console.log("close : ", e));
ws.addEventListener('message', (e) => {
console.log("message : ", e);
const container = document.querySelector("#data");
data.insertAdjacentHTML('beforeend', `<li class="list-group-item">\${e.data}</li>`);
});
document.querySelector("#sendBtn").addEventListener('click', (e) => {
ws.send(document.querySelector("#message").value);
});
</script>
/echo로 연결 되었으므로 echoHandler를 거치게 될 것입니다.
또한 메세지를 입력 후 sendBtn를 클릭하면 ws에 해당 메세지를 보내도록 처리하였고, 메세지를 받으면 ul태그 하위에 li태그를 만들어 해당 메세지 내용을 출력하도록 하였습니다.
- send버튼을 클릭하여 /echo 웹소켓에 메세지 send
- echoHandler의 handleTextMessage 메소드에서 받아 해당 메세지를 각 세션(WebSocketSession)들에게 전달
- 클라이언트 측(ws.jsp)의 message event에 의해 message를 받아 후처리
open시
@콘솔출력값
DEBUG: com.ce.spring2.ws.controller.EchoHandler - [add 현재 세션수 1] 1fc27edc-2607-59b0-822a-0a26b65ab3c6
message송부 시
@콘솔출력값
DEBUG: com.ce.spring2.ws.controller.EchoHandler - [message] df9c80bc-5088-3f4b-3e5d-e18a2c5af8df : 안녕
※ 메세지만 보고싶다면, echoHandler에서 message.getPayload()로 변경
// 메세지만 보고싶다면 아래 코드로 변경
for(WebSocketSession sess : sessionList) {
sess.sendMessage(new TextMessage(session.getId() + ":" + message.getPayload()));
}
두 개의 브라우저에서 접속
@콘솔출력값
DEBUG: com.ce.spring2.ws.controller.EchoHandler - [add 현재 세션수 2] d94da243-1359-f083-3fe5-a03bff66819b
DEBUG: com.ce.spring2.ws.controller.EchoHandler - [message] 15dd1fda-68c8-2740-0db4-bf70ab8503b8 : 안녕
DEBUG: com.ce.spring2.ws.controller.EchoHandler - [message] d94da243-1359-f083-3fe5-a03bff66819b : 안녕하십니까요 나는 검은브라우저
'Java > Spring' 카테고리의 다른 글
Spring) Spring-WebSocket - Stomp, Stomp 환경설정 및 흐름파악 (0) | 2022.09.14 |
---|---|
Spring) Spring-WebSocket + SockJS (0) | 2022.09.14 |
Spring) Security - 인증된 사용자 정보 가져오기, 처리 순서 파악 (2) | 2022.09.11 |
Spring) Security - DB에 있는 사용자 조회(로그인 처리), UserDetails/UserDetailsService (2) | 2022.09.11 |
Spring) Security - 로그인 후처리 (0) | 2022.09.11 |