[Java] 웹 소켓 (WebSocket)


Development note/Java  2015.02.15 23:22

안녕하세요. 명월입니다.


이번 포스트는 Websocket에 대해서 공부하겠습니다. WebSocket은 클라이언트(웹 브라우저)와 서버(웹 서버)가 양방향 통신하는 것을 말합니다.


사용 방법으로는 Ajax와 비슷하지만 개념 면에서 Ajax와 차이를 두고 있습니다.

Ajax의 경우는 웹 브라우저에서 데이터를 호출하면 웹 서버에서 호출된 값을 검색, 작성해서 웹 브라우저로 메시지를 보내는 형식의 구조라면 웹 소켓의 경우는 웹 브라우저에서 호출해서 데이터를 가져가는 기능 포함 반대로 서버에서 클라이언트를 호출할 수 있는 기능까지 있습니다.

예로 채팅프로그램을 만든다고 가정할 때 우리가 채팅 글을 써서 서버로 보내는 건 가능합니다. 그러나 Ajax로 만든 웹 페이지라면 서버 측에서 클라이언트로 보낼 수가 없으므로 대응책으로는 10초마다 데이터를 데이터 갱신을 통해서 데이터를 확인할 수 있지만 웹 소켓은 서버에서도 클라이언트를 인지를 하는 상태이기에 양방향 통신이 가능합니다.

웹 소켓의 경우는 HTML 5.0부터 표준이 되고 사용 프로토콜 형태는 ws://~~ 형태로 사용합니다.


개인적인 생각이지만 웹 소켓이 발전하게 되면 앞으로 Ajax개념은 사라질 듯싶습니다. 그러나 현재로는 websocket의 서버부하, 보안(Security)적인 측면과 세션 관리 등의 여러 가지 문제를 가지고 있고 가장 큰 단점으로는 구 브라우저(IE 8.0)에서는 작동하지 않는 문제점이 있습니다.

그러나 웹 소켓이 가지고 있는 매력은 분명히 있으므로 어떤 형태로든 발전하지 않을까 싶습니다.


이제부터 소스 구현을 통해 사용방법을 자세히 알아보겠습니다.

import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.server.ServerEndpoint;
 
@ServerEndpoint("/websocket")
public class websocket {
  /***
   * 웹 소켓이 연결되면 호출되는 이벤트
   */
  @OnOpen
  public void handleOpen(){
    System.out.println("client is now connected...");
  }
  /**
   * 웹 소켓으로부터 메시지가 오면 호출되는 이벤트
   * @param message
   * @return
   */
  @OnMessage
  public String handleMessage(String message){
    System.out.println("receive from client : "+message);
    String replymessage = "echo "+message;
    System.out.println("send to client : "+replymessage);
    return replymessage;
  }
  /**
   * 웹 소켓이 닫히면 호출되는 이벤트
   */
  @OnClose
  public void handleClose(){
    System.out.println("client is now disconnected...");
  }
  /**
   * 웹 소켓이 에러가 나면 호출되는 이벤트
   * @param t
   */
  @OnError
  public void handleError(Throwable t){
    t.printStackTrace();
  }
}

구현 방법은 생각보다 복잡하지 않습니다. 기본적인 네 가지의 어노테이션을 통해 함수를 만들 수 있습니다.


OnOpen은 서버 측에서 클라이언트와 웹 소켓 연결이 되었을 때 호출되는 함수입니다.

OnMessage는 클라이언트에서 서버 측으로 메시지를 보내면 호출되는 함수입니다.

OnClose는 웹 소켓이 끊겼을 때, 마지막으로 OnError는 웹 소켓이 에러가 나면 발생을 하는 이벤트입니다.


이번엔 클라이언트에서 웹 소켓을 접속하는 방법에 대해 공부하겠습니다.

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
  <form>
    <!-- 송신 메시지 작성하는 창 -->
    <input id="textMessage" type="text">
    <!-- 송신 버튼 -->
    <input onclick="sendMessage()" value="Send" type="button">
    <!-- 종료 버튼 -->
    <input onclick="disconnect()" value="Disconnect" type="button">
  </form>
  <br />
  <!-- 결과 메시지 보여주는 창 -->
  <textarea id="messageTextArea" rows="10" cols="50"></textarea>
  
  <script type="text/javascript">
    //WebSocketEx는 프로젝트 이름
    //websocket 클래스 이름
    var webSocket = new WebSocket("ws://localhost:8080/WebSocketEx/websocket");
    var messageTextArea = document.getElementById("messageTextArea");
    //웹 소켓이 연결되었을 때 호출되는 이벤트
    webSocket.onopen = function(message){
      messageTextArea.value += "Server connect...\n";
    };
    //웹 소켓이 닫혔을 때 호출되는 이벤트
    webSocket.onclose = function(message){
      messageTextArea.value += "Server Disconnect...\n";
    };
    //웹 소켓이 에러가 났을 때 호출되는 이벤트
    webSocket.onerror = function(message){
      messageTextArea.value += "error...\n";
    };
    //웹 소켓에서 메시지가 날라왔을 때 호출되는 이벤트
    webSocket.onmessage = function(message){
      messageTextArea.value += "Recieve From Server => "+message.data+"\n";
    };
    //Send 버튼을 누르면 실행되는 함수
    function sendMessage(){
      var message = document.getElementById("textMessage");
      messageTextArea.value += "Send to Server => "+message.value+"\n";
      //웹소켓으로 textMessage객체의 값을 보낸다.
      webSocket.send(message.value);
      //textMessage객체의 값 초기화
      message.value = "";
    }
    //웹소켓 종료
    function disconnect(){
      webSocket.close();
    }
  </script>
</body>
</html>

처음에 소개한 대로 웹 소켓은 ws의 프로토콜로 시작합니다. WebSocket란 javascript의 내장함수를 호출해서 선언 파라미터에 웹 소켓 서버 주소를 입력합니다.

서버 측과 비슷하게 onopen, onmessage, onclose, onerror의 네 함수가 존재합니다.

onopen은 웹소켓이 연결되었을 때, onmessage는 서버로부터 메시지가 도착할 때, onclose는 서버와 연결이 끊겼을 때, onerror는 에러가 발생할 때 호출하는 함수입니다.

tomcat으로 서버를 기동시켜서 웹 페이지를 열면 위와 같은 화면이 나옵니다. 정상적인 접속이 되면 connect...라는 메시지가 나옵니다. 웹 소켓의 로직은 간단하게 클라이언트에서 메시지를 보내면 echo라는 메시지만 붙여서 보내는 형식이 됩니다. test를 보내니 echo test라는 답신이 왔네요.

WebSocketEx.zip


댓글 6개가 달렸습니다.
댓글쓰기
  1. 초보
    2015.11.12 17:20 |  수정/삭제  댓글쓰기

    WebSocket 의 url을 모르겠네요..

    혹시 파일 저장 경로 등은 볼수 없을까요?ㅜㅜ

    • 明月 v명월v
      2016.03.22 20:10 신고 |  수정/삭제

      답변이 매우 늦었네요...죄송합니다.
      url은 클래스 이름입니다.
      ws://호스트명/프로젝트명/클래스이름

  2. asdjl
    2016.10.06 11:11 |  수정/삭제  댓글쓰기

    글 잘읽었어요.
    죄송한데 소스좀 부탁드려요.
    감사합니다.

  3. com
    2016.10.18 13:19 |  수정/삭제  댓글쓰기

    websocket 예제 코드를 실행하려고 하는데 eclipse에서 java 코드를 실행 할 수 없네요 @ServerEndpoint 처리 코드를 eclipse에서 어떻게 설정하고 입력해야 java코드를 실행 시킬 수 있나요? 혹시 프로젝트 파일이라도 올려 주시면 고맙겠습니다.


  4. 2016.11.28 21:00 |  수정/삭제  댓글쓰기

    비밀댓글입니다

  5. 웹소켓
    2017.07.19 18:49 |  수정/삭제  댓글쓰기

    그대로 따라했는데 error... disconnect... 메시지만 나오고 통신이 안되네요... ㅜㅜ