최신 게시글(JAVA)
2019.01.13 / 22:15

웹소켓 서버 만들기

hanulbit
추천 수 58

환경은,

Spring 4

Tomcat 7.0

JDK 1.7 


아래는 WEBSocket Server 이고 

JAVAX 7 api에서 제공하는 어노테이션을 사용해서 서버를 구축해본다.

물론 @ServerEndpoint 라는 어노테이션을 통해 이 클래스는 서버라는 것을 명시한다

싱글톤 패턴으로 관리된다.


@ServerEndpoint란

이 어노테이션을 명시함으로서 WEB 소켓으로 접속 가능한 URL 정보를 명시하여 소켓 서버를 생성해주며 프로퍼티를 통해 decoder나 encoder를 명시할 수 있다. 


JAVA

import javax.websocket.OnClose;

import javax.websocket.OnMessage;

import javax.websocket.OnOpen;

import javax.websocket.Session;

import javax.websocket.server.ServerEndpoint;

import net.sf.json.JSONObject;

import org.springframework.stereotype.Component;

import com.ese.util.log.COMLog;


/**

 * WebSocket Server

 * @author GOEDOKID

 * @since 2015.03.17

 * @category class

 * @version 0.1

 */

@Component

@ServerEndpoint("/echo")

public class SocketServer {


static Set<Session> sessionUsers = Collections.synchronizedSet(new HashSet<Session>());

/**

 * When the client try to connection to websocket server,

 * open session and add information to the collection.

 *

 * @author GOEDOKID

 * @since 2015. 3. 18. 

 * @param Session userSession

 * @return

 */

@OnOpen

public void handleOpen(Session userSession) {

COMLog.info("WebSocket : Client Session is Open. ID is "+ userSession.getId());

sessionUsers.add(userSession);

}


/**

 * Send to message designated client by "websocket.send()" command.

 *

 * @author GOEDOKID

 * @since 2015. 3. 18. 

 * @param String message

 * @return

 */

@OnMessage

public void handleMessage(String message) throws IOException {

Iterator<Session> iterator = sessionUsers.iterator();

COMLog.info("WebSocket : Send message to all client.");

if(sessionUsers.size() > 0) {

while(iterator.hasNext()) {

iterator.next().getBasicRemote().

                   sendText(JSONConverter(message, "message", "event"));

}

} else {

COMLog.info("WebSocket : Here is no registered destination.");

}

}


/**

 * Session remove When browser down or close by client control

 * 

 * @author GOEDOKID

 * @since 2015. 3. 18. 

 * @param 

 * @return

 */

@OnClose

public void handleClose(Session session) {

COMLog.

info("WebSocket : Session remove complete. ID is "+session.getId());

sessionUsers.remove(session);

}

public String JSONConverter(String message, String command, String type) {

JSONObject jsonObject = new JSONObject();

jsonObject.put("type", type);

jsonObject.put("command", command);

jsonObject.put("message", message);

return jsonObject.toString();

}

}


간단한 구현을 통해서 클래스 하나를 WebSocket Client를 받을 수 있는 서버로 구축할 수 있고 JAVAX 7 api를 통해서 어노테이션을 import할 수 있다. 만약에 개발환경이나 pom.xml에 javax 7에 대해 dependency가 명시되어 있지 않다면 에러가 날 수 있다.


JSP

var _ws = null;

_ws = window.WebSocket ? new WebSocket(url) : null;


_ws.onmessage = function(event){

msg = JSON.parse(event.data);

if(msg.command == "message"){

switch(msg.type){

case "event":{

makeSomeNoise(msg.message);

break;

}

}

}

};


최초 웹 소켓이 생성되는 시점에서 @OnOpen 어노테이션이 명시된 method를 인지하여 session을 open하게 된다. 

그리고 

@onMessage를 통해서 송신된 데이터는 아래의 _ws.onmessage를 통해서 수신할 수 있다.


원래 WebSocket 이전에는 실시간 서버와 데이터를 송신하는 부분에 대해서 롱 폴링이나 코멧 방식으로 데이터를 실시간으로 가져오기는 했지만 내부적으로 ajax를 통해서 항상 서버에 데이터가 존재하는지에 대해서 체크할 필요가 있엇다. 항상 브라우저는 무슨 일을 하고 있었고 리소스 점유에 대한 이슈가 있었다. 


하지만 WebSocket을 통해서 편하게 실시간 데이터를 주고 받을 수 있게 됐다.


참고.

1. 알고보니 @ServerPoint 등등 이런 어노테이션은 tomcat 7.0.4 이상 버전에 포함하고 있는 라이브러리에서 지원한다. 이전 버전일아 명시된 버전 이상에서 라이브러리가 상이하게 포함하고 있는 걸 확인했다.