웹 소켓(Web Socket) 서버로 채팅하기
Java에서는 WebSocket을 이용해 웹 소켓 서버를 구축할 수 있다.
ChatServerEndPoint.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | package com.newlecture.web.service; import java.io.IOException; import java.util.Collections; import java.util.HashSet; import java.util.Set; import javax.websocket.EndpointConfig; import javax.websocket.OnClose; import javax.websocket.OnMessage; import javax.websocket.OnOpen; import javax.websocket.Session; import javax.websocket.server.ServerEndpoint; import com.google.gson.Gson; //소켓 ip(건물번호)+port(사서함번호)+web @ServerEndpoint("/resource/chatserver") public class ChatServerEndPoint { private static Set<Session> clients; //static 생성자로 생성해줌. static{ //누군가 쓰레드를 읽고 있을 때, 조작을 할 수 없게 Lock을 걸 수 있는 컬렉션을 이용해야함. //Set 생성 시, 동기화된 컬렉션을 생성해줌. => synchronizedSet()이용 clients = Collections.synchronizedSet(new HashSet<Session>()); } @OnOpen public void onOpen(Session session, EndpointConfig config){ System.out.println(session.toString()+"Connected"); clients.add(session); } @OnMessage public void onTextMessage(Session session, String data) throws IOException{ //Gson.fromJson : JSON을 Java의 Object로 변환해준다. //id와 msg가 담긴 JSON을 담을 Object형이 없으므로, ChatData라는 Object를 하나를 만들어준다. ChatData chatData = new Gson().fromJson(data, ChatData.class); System.out.println("id"+chatData.getId()+"msg:"+chatData.getMsg()); for(Session s:clients) s.getBasicRemote().sendText(data); } @OnClose public void onClose(Session session){ System.out.println("클라이언트 접속이 해제 되었습니다."); clients.remove(session); System.out.println(session.toString()+"DisConnected"); } } | cs |
@ServerEndPoint 어노테이션으로 서버 url을 매핑해준다. 여기선 /resource/chatserver로 매핑하였다.
private static Set<Session> clients;
session을 Collection(Set, List, Map) 중에서 Set 컬렉션에 넣어준다.
참고 : List는 중복 허용되는 순서가 있는 집합, Set은 중복 허용없는 순서 유지 없는 집합, Map은 key-value의 집합)
static 생성자는 요청 시 매번 생성되는 인스턴스 생성자와 달리, 한 번 생성되면 다시는 생성되지 않는다.
여기서는 요청된 Session을 저장할 목적이므로, 요청마다 생성되면 기존의 session이 날라가버리니 Static생성자를 이용한다.
Collections.synchronizedSet이란, Session별 쓰레드 생성 시, 누군가 R(Read)하고 있을 때 CUD(Create,Update,Delete)를 불가능하게 하는 동기적 특성을 갖게하는 것이다. 다시 말해, 동시 접근 불가능하게 해주는 컬렉션이다.!!!
여기선 누군가 session을 조작할 때, 다른 사람이 접근하면 안되므로, 이 기능을 사용한다.
@onOpen마다 접속자 정보를 clients의 컬렉션에 저장한다. 마찬가지로 @onClose되면 clients로부터 해당 접속자를 제거해준다.
@onTextMessage는 데이터를 받았을 때, 이를 처리하는 메소드이다.
현재 data는 Json 형식으로 날라가고 있는데, 이를 java의 Object로 변환하기 위해 GSON을 쓴다.
GSON? Object<->JSON 해주는 라이브러리이다.
GSON.fromJSON(JSON 명, 객체 명.class ) : JSON -> Object로 명시한 Object로 바꿔 반환해준다.