2013년 2월 4일 월요일

WebSocket, Atmosphere, Tomcat 예제 웹소켓

2013-10-05 
여름을 지나면서 웹로직까지 websocket을 지원하게 돼었으므로
해당 WAS의 예제를 검색하여 사용하십시오.
-----------------
java WAS에서 websocket을 안정되게 지원하는 Atmosphere 예제다.
server-Window7 x64, java7 x64, tomcat 7.34, Atmosphere
client-Window7 x64, Chrome,Firefox,Opera,IE10

javatomcat 이 준비되었다면
http://maven.apache.org/ 에서 maven을 다운받아 환경을 잡고
http://github.com/Atmosphere/atmosphere 에서 zip으로 다운받아
maven으로 compile,package를 돌려준다.

https://github.com/Atmosphere/atmosphere/wiki
https://github.com/Atmosphere/atmosphere/wiki/Structure-of-an-Atmosphere's-Application
https://github.com/Atmosphere/atmosphere/wiki/Understanding-WebSocketHandler
를 참조하여 필요한 파일들을 찾아서 lib,web.xml,context.xml등을 톰캣에 복사한다.
web.xml


    <servlet>
        <description>AtmosphereServlet</description>
        <servlet-name>AtmosphereServlet</servlet-name>
        <servlet-class>org.atmosphere.cpr.AtmosphereServlet</servlet-class>
        <load-on-startup>0</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>AtmosphereServlet</servlet-name>
        <url-pattern>/websocket/atmosphere/*</url-pattern>
    </servlet-mapping>

다음은 java 소드다.

package test.ws;

import java.io.IOException;
import java.util.Date;

import org.atmosphere.config.service.WebSocketHandlerService;
import org.atmosphere.cpr.AtmosphereRequest;
import org.atmosphere.cpr.AtmosphereResource;
import org.atmosphere.cpr.Broadcaster;
import org.atmosphere.cpr.BroadcasterFactory;
import org.atmosphere.util.SimpleBroadcaster;
import org.atmosphere.websocket.WebSocket;
import org.atmosphere.websocket.WebSocketHandlerAdapter;
import org.atmosphere.websocket.WebSocketProcessor.WebSocketException;
import org.codehaus.jackson.map.ObjectMapper;

@WebSocketHandlerService(path = "/websocket/atmosphere/simple", broadcaster = SimpleBroadcaster.class)
public class AtmosphereSample extends WebSocketHandlerAdapter
{
private final ObjectMapper mapper = new ObjectMapper();
public void onByteMessage(WebSocket socket, byte[] arg1, int arg2, int arg3) throws IOException
{
// TODO Auto-generated method stub

}

public void onClose(WebSocket socket)
{
AtmosphereResource resource = socket.resource();
AtmosphereRequest request = resource.getRequest();
String uri = request.getRequestURI();
String remote = request.getRemoteHost();
System.out.println("socket closed:" + uri + " from " + remote);
}

public void onError(WebSocket socket, WebSocketException e)
{
System.out.println("socket error:" + e.getLocalizedMessage());
}

public void onOpen(WebSocket socket) throws IOException
{
AtmosphereResource resource = socket.resource();
AtmosphereRequest request = resource.getRequest();
String uri = request.getRequestURI();
String remote = request.getRemoteHost();
System.out.println("socket opened:" + uri + " from " + remote);
socket.resource().setBroadcaster(BroadcasterFactory.getDefault().lookup("/simple", true));
}

public void onTextMessage(WebSocket socket, String message) throws IOException
{
// socket.write(socket.resource().getResponse(),message);
        AtmosphereResource r = socket.resource();
        Broadcaster b = r.getBroadcaster();
        b.broadcast(mapper.writeValueAsString(message));
}
}

다음은 jsp? 또는 html로

<%@ page contentType="text/html;charset=utf-8" pageEncoding="utf-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
</head>
<body>
<textarea id="marea" style="width:400px;height:300px">
</textarea>
<br/>
<input id="newbutton" type="button" value="new" onclick="fNewSocket('ws://localhost/websocket/atmosphere/simple')"  style="visibility:visible"/>
<input type="text" id="send"></input>
<input id="sendbutton" type="button" value="send" onclick="fSendMessage()" style="visibility:hidden"/>
<input id="closebutton" type="button" value="close" onclick="socket.close()" style="visibility:hidden"/>
</body>
<script id="script" type="text/javascript" src="/js/jquery/jquery-1.9.0.js"></script>
<script id="script" type="text/javascript" src="/js/jquery/jquery.atmosphere.js"></script>

<script type="text/javascript">
var tarea = document.getElementById("marea");

var data = [];
var socket;
function fNewSocket(uri)
{
try
{
if(socket && socket.readState != 3) socket.close();
window.WebSocket = window.WebSocket || window.MozWebSocket;
socket = new WebSocket(uri);
socket.onopen = function(msg) { 
tarea.value += "opened:"+socket.readyState+"\n";
}; 
socket.onerror = function(e) { 
tarea.value += e.data+"\n";
}; 
socket.onclose = function(e) { 
tarea.value += "closed:"+e.code+","+e.reason+":"+socket.readyState+"\n";
document.getElementById("sendbutton").style.visibility = "hidden";
document.getElementById("closebutton").style.visibility = "hidden";
document.getElementById("newbutton").style.visibility = "visible";
}; 
socket.onmessage = function(message) {
try
{
var s = message.data;
tarea.value += message.data+"\n";
}
catch(ex)
{
alert(ex)
}
};
document.getElementById("newbutton").style.visibility = "hidden";
document.getElementById("sendbutton").style.visibility = "visible";
document.getElementById("closebutton").style.visibility = "visible";
}
catch( e)
{
tarea.value = e.toString();
}
}
function fSendMessage()
{
socket.send(document.getElementById("send").value);
}

window.unload = function(){
if(socket.readyState != 3) socket.disconnect();
}


</script>
</html>
------------------------------------
단순한 chat예제이다. win7-IE10,Chrome,Firefox,Opera는 다 잘 동작한다.
Safari, osx ios 환경에서 chrome등은 동작하지 않는다.
Safari는 6.x에서부터 제대로 지원할 것이라고 하고, 
osx,ios의 속사정은 모르겠다. chrome의 문제인지 os의 문제인지..

websocket 형태의 필요가 대두된지는 오래되었다.
websocket도 2008~9년부터 이야기가 본격화 되었어도 이제 겨우 여기까지 왔다.

websocket의 활용범위는 ajax는 비교되지 않는다.
벌써 이용하고 있는 곳도 적지 않다.

개발자들에게 상당한 자유도를 줄 것으로 보인다.

댓글 없음:

댓글 쓰기