본문 바로가기
Java/Spring

Spring) Spring-WebSocket (관련 설정)

by 박채니 2022. 9. 14.
안녕하세요, 코린이의 코딩 학습기 채니 입니다.
개인 포스팅용으로 내용에 오류 및 잘못된 정보가 있을 수 있습니다.

 

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 : 안녕하십니까요 나는 검은브라우저