JSP에서 실시간으로 통신을 사용할 때 소켓을 이용하게 된다.
미리 구현이 되어 있기 때문에 선언만 하고 메소드를 사용하게 된다.
기본 형태는 JSP에서 Jquery 형식으로 스크립트에 작성하게 된다.
JSP 스크립트 < - > 서블릿과 유사한 ServerEndPoint로
맵핑된 주소로 실시간으로 통신을 하게된다.
기본형태
// 먼저 페이지 시작 시 바로 getConnection 함수를 호출해 Server와 연결한다고 선언
$(function(){
getConnection();
})
// getConnection이 호출 될 때 연결을 위해 사용하는 메소드들
function getConnection(){
ws = new WebSocket("ws://localhost:8001" + '<%=request.getContextPath()%>/serverStart');
// 서버 시작할 때 동작
ws.onopen = function(event){
}
// 서버로부터 메세지를 전달 받을 때 동작하는 메소드
// 아래에 선언 할 onMessage로 event가 전달된다.
ws.onmessage = function(event){
onMessage(event);
}
// 서버에서 에러가 발생할 경우 동작할 메소드
ws.onerror = function(event){
onError(event);
}
// 서버와의 연결이 종료될 경우 동작하는 메소드
ws.onclose = function(event){
onClose(event);
}
}
// 전달할 String형 msg를 ws.send를 통해서 소켓으로 전달한다.
function send(msg){
ws.send(msg);
}
// 서버에서 메시지를 전달 받을 때 event 매개변수로 값을 받고
// 이 메소드에서 event 값을 통해 무엇을 할 것인지 정한다.
function onMessage(event){
// String 형태로 데이터가 넘어오므로 구분자를 통해서 사용하면 된다.
// 구분을 "메세지:구분:아이디"와 같다고 할 때
// 만약 event값이 "메세지내용:msg:3"과 같이 전달 되었다면
// ":"를 split 메소드를 이용하여 분리하면 담긴 변수에는
// serverMessage[0] = "메세지내용"
// serverMessage[1] = "msg"
// serverMessage[2] = "3"
// 위와 같이 분리된다.
// 아래의 예처럼 if문을 이용해서 잘 쓰면 된다.
var serverMessage = event.data.split(":");
if(serverMessage[1] == "msg") // msg, 메세지일 때
alert(serverMessage[2] + "님의 메세지 : " + serverMessage[0]);
} else if (serverMessage[1] == "alarm") {
alert("알람이 있습니다."):
}
}
// 소켓통신 에러 발생 시
function onError(event){
alert(event.data);
}
// 소켓통신이 끝낫을 때
function onClose(event){
alert(event);
}
body 부분에서는 예를들어 버튼에다가
<button onclick="send("안녕하세요:msg:3")"></button>
위와 같이 버튼이 있고 클릭하면 위에서 선언된 메소드인 send가 실행되어
ws.send()로 소켓을 통해 서버로 메세지가 전달이 된다.
다음은 서버에서 메세지를 받을때 파일의 예
코드를 보면 어노테이션을 통해 @ServerEndpoint("/auctionStart") 를 통해서 맵핑이 이루어져 있고
ws = ~~~~ 하고 위에서 Jquery로 선언한 부분에 주소가 맞으면
이 EndPoint를 통해서 통신을 하게 된다.
import java.io.IOException;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
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;
@ServerEndpoint("/auctionStart")
public class AuctionStart {
private static Set<Session> clients = Collections.synchronizedSet(new HashSet<Session>());
@OnOpen
public void onOpen(Session session) {
//서버 연결한 시점에 동작하는 메소드
//기존 사용자 리스트에 새로 연결 요청이 들어온 사용자를 추가한다
clients.add(session);
}
@OnMessage
public void onMessage(String msg, Session session) throws IOException {
//서버로부터 데이터를 전송받을 경우 동작할 메소드
System.out.println(msg);
//하나의 일 처리를 수행하는동안 사용자의 변경이 일어나면 안된다.
//즉 NullPointer를 방지하기 위해 동기화 처리를 해준다.
synchronized(clients) {
for(Session client : clients) {
client.getBasicRemote().sendText(msg);
}
}
}
@OnError
public void onError(Throwable e) {
//데이터를 전달하는 과정에서 에러가 발생할 경우 동작하는 메소드
e.printStackTrace();
}
@OnClose
public void onClose(Session session) {
//지워주지 않으면 Set에 이미 나간 사용자가 남아있기 때문에 메세지 전송시 에러 난다.
clients.remove(session);
}
}
private static Set<Session> clients = Collections.synchronizedSet(new HashSet<Session>());
위의 선언을 통해서 현재 통신 시점의 모든 Session들의 정보를 담는다.
다른 부분은 건들일 일이 없는데 @OnMessage 이쪽 부분만 잘 사용하면 된다.
OnMessage 메소드를 통해서 전달된 String형 메세지가 이쪽으로 전달되고
데이터를 처리 한 후
synchronized(clients) {
for(Session client : clients) {
client.getBasicRemote().sendText(msg);
}
}
synchronized 부분에서 아까 담았던 모든 session에게 해당 메세지를 전달한다.
client.getBasicRemote().sendText(msg); 이 부분을 수정하여
client의 값에서 id값과 같은 키값을 뽑아 조건문을 통해서
특정 대상만 구분하여 메세지를 보낼 수 있다.
synchronized 바로 윗 부분에서 msg 데이터를 마음대로 가공해도 되고 Service, Dao를 거쳐서
새로운 msg를 만들어도 된다.
결론
Endpoint 서버와 연결(이 때부터 소켓(ws)는 onMessage(event)를 계속 기다리고 있다.)
- ws.send를 통해 서버에 메세지 전달
- 서버에서 데이터 처리 후 세션에 데이터 전송
- 서버에서 메시지가 도착하면 onMessage(event)로 처리
메세지는 전부 String형으로 잘 컨트롤 해야 한다.
'JDBC, Servlet, JSP, Ajax, Json, Gson > 03.Ajax, Json, Gson 사용법' 카테고리의 다른 글
[Ajax, Json, Gson]03-01. Ajax( Json, Gson ) 설명 및 설정 방법 (0) | 2018.12.21 |
---|