반응형

Spring MVC 기반 Spring WebSocket4.x를 이용하여 Client와 Server 간 양방향 통신과 Server에서 Client로 메시지(Text ro JSON)를 주기적으로 Broadcast 하는 예제를 따라 하기 식으로 설명을 드리려고 합니다.

1. WebSocket 이란?

더보기

Socket에 대한 개념을 모두 알고 계시고 참고 할만한 포스팅들이 많기 때문에 간략하게 설명만 하고 넘어가겠습니다.

Socket은 간단하게 클라이언트와 서버 간 양방향 정보(데이터)를 주고받기 위한 통로라고 생각하시면 되고요

WebSocket은 HTTP 환경에서 양방향 통신을 지원하기 위한 프로토콜로 RFC 6455로 2011년 12월에 등장했고 이후 HTML5 표준에도 지정되었습니다. HTTP 프로토콜을 기반으로 하므로 기존 요청-응답처럼 80(or 443)에서 Handshake 후 ws(or wss)로 프로토콜을 변환해서 커넥션을 맺는 구조입니다.

2. Spring 4.x WebSocket

더보기

스프링 4.x부터는 WebSocket을 아래와 같이 지원합니다.

3. Spring MVC Project를 이용한 예제

3-1. Spring MVC Project 생성

더보기

※ 이클립스 STS 설치 참조 : https://meyouus.tistory.com/10

Project명 : SocketTest
package명 : com.forever.mysocket

java : 1.8

 

 

 

 

http://localhost:8080/mysocket

3-2. pom.xml 수정

더보기

3-2-1. Spring 버전 4.3.9로 변경

<properties>
  <java-version>1.8</java-version>
  <org.springframework-version>4.3.9.RELEASE</org.springframework-version>
  <org.aspectj-version>1.6.10</org.aspectj-version>
  <org.slf4j-version>1.6.6</org.slf4j-version>
</properties>

3-2-2. Websockt , jackson 추가

<!-- 웹 소켓 -->
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-websocket</artifactId>
  <version>4.3.9.RELEASE</version>
</dependency>
<!-- jackson -->
<dependency>
  <groupId>com.fasterxml.jackson.core</groupId>
  <artifactId>jackson-databind</artifactId>
  <version>2.9.5</version>
</dependency>

3-2-3. Maven 완료

pom.xml
0.01MB

3-3. WebSocketHandler Class 생성

서버 쪽 Socket 처리 Class

- afterConnectionClosed() : 클라이언트가 연결을 끊었을 때 실행

- afterConnectionEstablished() : 클라이언트가 서버로 연결된 이후에 실행

- handleMessage() : 클라이언트가 서버로 메시지를 전송했을 때 실행

- handleTransportError() : 연결된 클라이언트에서 예외 발생 시 실행

- broadcast : 서버에서 Client로 메시지 전송

- afterPropertiesSet : Test를 위하여 생성 , Thred로 3초마다 증가된 값을 연결된 Client에 Broadcast.

// 클라이언트가 연결을 끊었을 때 실행
@Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
  super.afterConnectionClosed(session, status);
  sessionSet.remove(session);
  this.logger.info("remove session!");
}

// 클라이언트가 서버로 연결된 이후에 실행
@Override
public void afterConnectionEstablished(WebSocketSession session)throws Exception {
  super.afterConnectionEstablished(session);
  sessionSet.add(session);
  this.logger.info("add session!");
}

// 클라이언트가 서버로 메세지를 전송했을 때 실행
@Override
public void handleMessage(WebSocketSession session, WebSocketMessage<?> message) throws Exception {
  super.handleMessage(session, message);
}

// 연결된 클라이언트에서 예외 발생 시 실행
@Override
public void handleTransportError(WebSocketSession session,Throwable exception) throws Exception {
this.logger.error("web socket error!", exception);
}    

// 연결된 Client에 메시지 Broadcast 목적
public void broadcast(String message){
}   

/**
* Bean 생성후 서버에서 Client로 주기적으로 메시지를 Broadcast 
* Test를 위하여 생성
* Thred로 3초마다 증가된 값을 연결된 Client에 Broadcast 한다.
*/
@Override
public void afterPropertiesSet() throws Exception {
  Thread thread = new Thread(){
  int i=0;
  @Override
  ~~~~~~~~~~~~
  ~~~~~~~~~~~~~
  thread.start();
}    

WebSocketHandler.java
0.00MB

3-4. servlet-context.xml 수정

     3-4-1.websocket 추가

xmlns:websocket="http://www.springframework.org/schema/websocket"
http://www.springframework.org/schema/websocket
http://www.springframework.org/schema/websocket/spring-websocket.xsd"

    3-4-2. Handler , path 지정

<beans:bean name="webSocketHandler" class="com.forever.mysocket.common.WebSocketHandler"/>
<websocket:handlers>
	<websocket:mapping path="/socket1" handler="webSocketHandler"/>
</websocket:handlers>

servlet-context.xml
0.00MB

3-5. Controller RequestMapping Path 추가

    3-5-1. '/SocketTest' Path 추가

@RequestMapping(value = "/SocketTest", method = RequestMethod.GET)
public String SocketTest(Locale locale, Model model) {
  logger.info("SocketTest The client locale is {}.", locale);

  return "SocketTest";
}

HomeController.java
0.00MB

3-6. View 파일 추가

    3-6-1. socket주소 지정

var wsUri = "ws://localhost:8080/mysocket/socket1";

   3-6-2. socket 연결(open)

var webSocket;
var myWebSocket = {
  openSocket : function() {
    webSocket = new WebSocket(wsUri);
    webSocket.onopen = function(evt) {
    // Socket Open
    writeToScreen("WebSocket Connection opened!");
    };
    webSocket.onmessage = function(evt) {
    // 서버로 부터 메시지 수신
    myWebSocket.handleMessage(evt.data);
    };

    webSocket.onerror = function(evt) {
    // Socket Error 발생
    myWebSocket.onError(evt)
    };

    webSocket.onclose = function(event) {
    // Socket 닫힘
    writeToScreen("Server Connection closed");
    };        
  },
  doSend : function(message) {
  // 서버로 메시지 전송
  webSocket.send(message);
  },
  handleMessage : function (data) {
  // 메시지 처리
  if(data != null){
  $("#serverMessage").val(data);
  writeToScreen(data);
  }
}

    3-6-3. 메시지 화면에 출력

function writeToScreen(message) {
  // 서버로 부터 수신된 메시지를 출력한다.
  var pre =document.createElement("p");
  pre.style.wordWrap = "break-word";
  pre.innerHTML = message;
  output.appendChild(pre);
  output.prepend(pre);
}

    3-6-4. Body

<body>
  <h1 style="text-align: center;">WebSocket Client Test</h1><br>
  <div style="text-align: center;">
     <form action="">
       <input id="sendBtn" value="Send" type="button">&nbsp;
       <input id="message" name="message" value="Have a good day" type="text"><br>
       Server Message : <input id="serverMessage" name="serverMessage" type="text"><br>
     </form>
  </div>
  <div id="output"></div>
</body>

SocketTest.jsp
0.00MB

4. Socket Test

     4-1. 화면설명

           ① 서버로 메시지 전송 ==> Socket에 연결된 모든 Client에게 전달

           ② 서버로부터 수신된 메시지 표시

           ③ 서버로 부터 수신된 메시지 이력 표시

        4-2. 동작 화면 동영상 캡처

https://youtu.be/iTXE-RoOhlA

5. 소스 파일

SocketTest.zip
0.01MB

감사합니다.

https://youtu.be/iTXE-RoOhlA
반응형
  • 네이버 블러그 공유하기
  • 네이버 밴드에 공유하기
  • 페이스북 공유하기
  • 카카오스토리 공유하기