본문 바로가기

Spring

Spring(13) - WebSocket

HTTP5의 주요 API중 하나인 웹소켓은 클라이언트와 서버간 양방향 통신을 지원하기 위한 표준이다. 자바의 웹소켓 표준에 맞춰서 개발을 하다보면 DispatcherServlet이나 스프링의 빈 객체를 사용하기가 매우 번거롭다. 그래서 스프링은 자체적인 클래스를 제공해주고 있는데 그것이 바로 WebSocketHandler이다. 먼저 의존설정을 해준다.

<dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-websocket</artifactId>
        <version>4.0.4.RELEASE</version>
</dependency>

웹소켓 서버를 구현할 때는 AbstractWebSocketHandler나 TextWebSocketHandler를 상속받아서 구현한다.


package my.com.ajax.controller;

import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;

public class EchoHandler extends TextWebSocketHandler {

	@Override
	public void afterConnectionEstablished(WebSocketSession session) throws Exception {
		// TODO Auto-generated method stub
		System.out.printf("%s 연결됨", session.getId());
	}

	@Override
	protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
		// TODO Auto-generated method stub
		System.out.printf("%s 로부터 [%s]받음", session.getId(), message.getPayload());
		session.sendMessage(new TextMessage("echo : " + message.getPayload()));
	}

	@Override
	public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
		// TODO Auto-generated method stub
		System.out.printf("%s 연결 끊김", session.getId());
	}
	

}

afterConnectionEstablished(), afterConnectionClosed()는 각각 웹소켓 클라이언트와 연결되거나 연결이 끊겼을때 호출이된다. 두 메서드의 WebSocketSession 파라미터는 클라이언트와의 세션을 관리하는 객체이다. HandleTextMessage()는 웹소켓 클라이언트가 텍스트 메시지를 전송할 때 호출되며, TextMessage()는 그 텍스트 메시지의 정보를 담고있다. session.sendMessage()는 데이터를 클라이언트에 전송할 때 사용되는데 TextMessage를 사용해 텍스트 데이터를 전송했다. 다음으로 웹소켓 활성화를 위해 스프링에 등록을해준다.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:context="http://www.springframework.org/schema/context"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns="http://www.springframework.org/schema/beans"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:websocket="http://www.springframework.org/schema/websocket"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
       http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
       http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
       http://www.springframework.org/schema/websocket http://www.springframework.org/schema/websocket/spring-websocket.xsd">

   
	
	<websocket:handlers>
		<websocket:mapping handler="echoHandler" path="/echo-ws"/>
	</websocket:handlers>
	<bean id = "echoHandler" class = "my.com.ajax.controller.EchoHandler"/>

</beans>

클라이언트가 /echo-ws로 접속하면 echoHandler빈을 이용해서 처리하는것을 나타낸다.

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script src = "js/jquery-1.11.0.min.js"></script>
<script>
	$(document).ready(function(){
		$('#sendBtn').click(function(){
			sendMessage();
		});
	});
	
	var wsocket;
	function sendMessage(){
		wsocket = new WebSocket("ws://localhost:8080/spring4/ehco-ws");
		wscoket.onmessage = onMessage;
		wsocket.onclose = onClose;
		wsocket.onopen = function(){
			wsocket.send($('#message').val());
		}
	}
	function onMessage(evt){
		var data = evt.data;
		alert("서버에서 데이터 받음" + data);
		wsocket.close();
	}
	function onClose(evt){
		alert("연결 끊김");
	}

</script>
</head>
<body>
	<input type = "text" id = "message"/>
	<input type = "button" id = "sendBtn" value = "전송"/>

</body>
</html>

뷰에서는 이렇게 자바스크립트를 이용해서 웹소켓통신을 할 수 있다.