Client 소스
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<style type="text/css">
input#chat {
width: 410px
}#console-container {
width: 400px;
}#console {
border: 1px solid #CCCCCC;
border-right-color: #999999;
border-bottom-color: #999999;
height: 170px;
overflow-y: scroll;
padding: 5px;
width: 100%;
}#console p {
padding: 0;
margin: 0;
}
</style>
</head>
<body>
<div>
<p><input type="text" placeholder="type and press enter to chat" id="chat" /></p>
<div id="console-container">
<div id="console"></div>
</div>
</div><script type="text/javascript">
var Chat = {};
Chat.socket = null;
Chat.connect = (function(host) {
if( "WebSocket" in window) {
Chat.socket = new WebSocket(host);
} else if( "MozWebSocket" in window ){
Chat.socket = new MozWebSocket(host);
} else {
Console.log("Error : 지원하지 않는 브라우저 입니다.");
return;
}
Chat.socket.onopen = function() {
Console.log("정보 : WebSocket 오픈!");
document.getElementById("chat").onkeydown = function(event) {
if( event.keyCode == 13 ) {
Chat.sendMessage();
}
};
};
Chat.socket.onclose = function() {
document.getElementById("chat").onkeydown = null;
Console.log("정보 : WebSocket 오픈 종료!");
};
Chat.socket.onmessage = function(message) {
console.log(message);
Console.log(message.data);
};
});Chat.initialize = function() {
if( window.location.protocol == "http:") {
Chat.connect("ws://" + window.location.host + "/websocket/chat");
} else {
Chat.connect("wss://" + window.location.host + "/websocket/chat");
}
};Chat.sendMessage = (function() {
var message = document.getElementById("chat").value;
if( message != "") {
Chat.socket.send(message);
document.getElementById("chat").value = '';
}
});var Console = {};
Console.log = (function(message) {
var console = document.getElementById("console");
var p = document.createElement("P");
p.style.wordWrap = "break-word";
p.innerHTML = message;
console.appendChild(p);
while (console.childNodes.length > 25) {
console.removeChild(console.firstChild);
}console.scrollTop = console.scrollHeight;
});Chat.initialize();
</script>
</body>
</html>
Server Source
package com.test.websocket.service;
import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;import org.slf4j.Logger;
import org.slf4j.LoggerFactory;@ServerEndpoint(value = "/websocket/chat")
// 클라이언트가 접속할 때 사용될 URI
public class ChatService {private static final Logger logger = LoggerFactory.getLogger(ChatService.class);
private static final String GUEST_PREFIX = "Guest";
private static final AtomicInteger connectionIds = new AtomicInteger(0);
private static final Map<String, Session> sessionMap = new HashMap<String, Session>();
private final String nickname;
// 클라이언트가 새로 접속할 때마다 한개의 Session 객체가 생성된다.
// Session 객체를 컬렉션에 보관하여 두고 해당 클라이언트에게 데이터를 전송할 때마다 사용한다
private Session session;public ChatService() {
// 클라이언트가 접속할 때마다 서버측에서는 Thread 가 새로 생성되는 것을 확인할 수 있다
String threadName = "Thread-Name:" + Thread.currentThread().getName();// getAndIncrement()은 카운트를 1 증가하고 증가되기 전의 숫자를 리턴한다
nickname = GUEST_PREFIX + connectionIds.getAndIncrement();
logger.info("생성자:" + threadName + ", " + nickname);
}@OnOpen
public void start(Session session) {
logger.info("클라이언트 접속 : " + session);
this.session = session;
sessionMap.put(nickname, session);String message = String.format("* %s %s", nickname, " 접속");
broadcast(message);
}@OnClose
public void close() {
sessionMap.remove(nickname);
String message = String.format("* %s %s", nickname, " 종료");
broadcast(message);
}@OnMessage
public void message(String message) {
String threadName = "Thread-name : " + Thread.currentThread().getName();
logger.info("메시지 도착 : " + threadName + ", " + nickname);
logger.info("메시지 : " + message );
if (null == message && "".equals(message))
return;String filteredMessage = String.format("%s: %s", nickname, message);
// Guest0의 메시지는 특정 클라이언트(Guest2)에게만 전달하는 경우
// if (this.nickname.equals("Guest0")) {
// sendToOne(filteredMessage, sessionMap.get("Guest2"));
// } else // 현재 접속된 모든 클라이언트에게 메시지를 전달하는 경우
// {
// broadcast(filteredMessage);
// }
broadcast(filteredMessage);
}@OnError
public void onError(Throwable t) throws Throwable {
System.err.println("오류/세션제거(" + nickname + "):Chat Error: " + t.toString());
sessionMap.remove(this.nickname);
}private void broadcast(String msg) {
Set<String> keys = sessionMap.keySet();
Iterator<String> it = keys.iterator();while (it.hasNext()) {
String key = it.next();
Session s = sessionMap.get(key);try {
s.getBasicRemote().sendText(msg);
} catch (IOException e) {sessionMap.remove(key);
try {
s.close();
} catch (IOException e1) {
e1.printStackTrace();
}String message = String.format("* %s %s", key, "has been disconnected.");
broadcast(message);
}}
}
private void sendToOne(String msg, Session ses) {
try {
ses.getBasicRemote().sendText(msg);
} catch (IOException e) {
e.printStackTrace();
}
}}
'HTML5' 카테고리의 다른 글
이미지 첨부시 미리보기 처리 (0) | 2015.07.06 |
---|---|
XMLHttpRequest level2를 사용하기 위한 Tomcat7 CORS 설정 (0) | 2015.06.01 |
지오로케이션 API 사용하기 (0) | 2015.05.29 |