- Java 로 구현
WebSocketConfig
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;
@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {
private final WebSocketHandler webSocketHandler;
private final WebSocketWidgetHandler webSocketWidgetHandler;
public WebSocketConfig(WebSocketHandler webSocketHandler, WebSocketWidgetHandler webSocketWidgetHandler){
this.webSocketHandler = webSocketHandler;
this.webSocketWidgetHandler = webSocketWidgetHandler;
}
@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
// 채팅방 웹소켓
registry.addHandler(webSocketHandler, "/ws/chat/{roomNumber}").setAllowedOrigins("*");
// top.html , 채팅방 목록 페이지에 적용
registry.addHandler(webSocketWidgetHandler, "/ws/widget/{username}").setAllowedOrigins("*");
}
}
WebSocketHandler - 채팅방 웹소켓
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@Component
public class WebSocketHandler extends TextWebSocketHandler {
// 접속중인 유저의 session 및 채팅방 정보를 담기위한 변수
List<HashMap<String, Object>> rls = new ArrayList<>();
// 메시지 send 할 때 동작
protected void handleTextMessage(WebSocketSession session , TextMessage message) throws Exception{
// 사용자가 전송한 데이터를 JSON 으로 변경
String payload = message.getPayload();
JSONObject obj = jsonToObjectParser(payload);
// 대화중인 채팅방 ID
String rN = String.valueOf(obj.get("roomId"));
// 같은 채팅방에 접속 중인 유저를 찾는다
HashMap<String, Object> temp = new HashMap<>();
if(rls.size() > 0){
for (int i = 0; i < rls.size(); i++) {
String roomId = (String) rls.get(i).get("roomId");
if(roomId.equals(rN)){
// session 정보를 담는다
temp = rls.get(i);
break;
}
}
for(String key : temp.keySet()){
if(key.equals("roomId")){
continue;
}
WebSocketSession wss = (WebSocketSession) temp.get(key);
if(wss != null){
try {
// 담은 session 정보가 null 이 아니라면 전달한다
wss.sendMessage(new TextMessage(obj.toJSONString()));
}catch (Exception e){
e.printStackTrace();
}
}
}
}
}
// client 접속
public void afterConnectionEstablished(WebSocketSession session) throws Exception{
super.afterConnectionEstablished(session);
// 접속정보가 있는지 확인하기 위한 변수
boolean flag = false;
String url = session.getUri().toString();
// 접속한 채팅방 id
String roomId = url.split("/ws/chat/")[1];
int idx = rls.size();
if(rls.size() > 0){
for (int i = 0; i < rls.size(); i++) {
// 접속정보가 있는 채팅방이 있는지 확인
String rN = (String) rls.get(i).get("roomId");
if (rN.equals(roomId)){
flag = true;
idx = i;
break;
}
}
}
if(flag){
// 자신의 session 정보를 넣는다
HashMap<String, Object> map = rls.get(idx);
map.put(session.getId(), session);
}else{
// session이 없는 방이라면 방id 와 자신의 session 정보를 넣는다
HashMap<String, Object> map = new HashMap<>();
map.put("roomId", roomId);
map.put(session.getId(), session);
rls.add(map);
}
// //websocket에 접속할때 session 정보가 필요하다면 사용
// JSONObject obj = new JSONObject();
// obj.put("type", "getId");
// obj.put("sessionId", session.getId());
//// session.sendMessage(new TextMessage(obj.toJSONString()));
// session.sendMessage(new TextMessage(session.getId()));
System.err.println(session + " client 접속");
}
// client 접속 해제
public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception{
System.err.println(session + "client 접속 해제");
if(rls.size() > 0){
for (int i = 0; i < rls.size(); i++) {
rls.get(i).remove(session.getId());
}
}
super.afterConnectionClosed(session, status);
}
// send 로 전달한 메세지 변환
private static JSONObject jsonToObjectParser(String jsonStr) {
JSONParser parser = new JSONParser();
JSONObject obj = null;
try {
obj = (JSONObject) parser.parse(jsonStr);
} catch (ParseException e) {
e.printStackTrace();
}
return obj;
}
}
WebSocketWidgetHandler - widget 용 웹소켓
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Set;
@Component
public class WebSocketWidgetHandler extends TextWebSocketHandler {
// 접속중인 유저의 session 및 채팅방 정보를 담기위한 변수
List<HashMap<String, Object>> rls = new ArrayList<>();
// 메시지 send 할 때 동작
protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
// 사용자가 전송한 데이터를 JSON 으로 변경
String payload = message.getPayload();
JSONObject obj = jsonToObjectParser(payload);
// 메시지를 받는 상대방 id
String id = String.valueOf(obj.get("userId"));
// 상대방 id를 가지고 session 정보를 찾아 담기 위한 변수
HashMap<String, Object> temp = new HashMap<>();
if (rls.size() > 0) {
for (int i = 0; i < rls.size(); i++) {
HashMap<String, Object> sessionId = rls.get(i);
if (sessionId.size() > 1 && sessionId.get("userId").equals(id)) {
// sessionId가 실제로 WebSocketSession 객체인지 확인
temp = sessionId;
temp.put("userId", id);
break;
}
}
}
for (String key : temp.keySet()) {
if (key.equals("userId")) {
continue;
}
WebSocketSession wss = (WebSocketSession) temp.get(key);
if (wss != null) {
try {
wss.sendMessage(new TextMessage(obj.toJSONString()));
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
// client 접속
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
super.afterConnectionEstablished(session);
boolean flag = false;
String url = session.getUri().toString();
String userId = url.split("/ws/widget/")[1];
int idx = rls.size();
if (rls.size() > 0) {
for (int i = 0; i < rls.size(); i++) {
String id = (String) rls.get(i).get(i);
if (id != null && id.equals(session.getId())) {
flag = true;
idx = i;
break;
}
}
}
if (flag) {
HashMap<String, Object> map = rls.get(idx);
map.put(session.getId(), session);
} else {
HashMap<String, Object> map = new HashMap<>();
map.put(session.getId(), session);
map.put("userId", userId);
rls.add(map);
}
System.err.println("client 접속");
}
// client 접속 해제
public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
System.err.println(session + "client 접속 해제");
if (rls.size() > 0) {
for (int i = 0; i < rls.size(); i++) {
// session.getId() 와 userId 를 정보를 가져와서 현재 자신의 sessionId 와 비교하여 삭제한다
Set[] test = new Set[]{rls.get(i).keySet()};
if(test[0].size() > 1 && test[0].toArray()[0].equals(session.getId())){
rls.remove(i);
}
}
}
super.afterConnectionClosed(session, status);
}
// send 로 전달한 메세지 변환
private static JSONObject jsonToObjectParser(String jsonStr) {
JSONParser parser = new JSONParser();
JSONObject obj = null;
try {
obj = (JSONObject) parser.parse(jsonStr);
} catch (ParseException e) {
e.printStackTrace();
}
return obj;
}
}
WebSocketHandler 은 채팅방 접속 시 연결되고,
WebSocketWidgetHandler 은 top.html 과 top.js 로 인하여 모든 페이지에서 동작 하게 된다
'개발 > Spring' 카테고리의 다른 글
[SpringBoot] WebSocket 채팅방 구현(4) - controller (0) | 2024.08.18 |
---|---|
[SpringBoot] WebSocket 채팅방 구현(3) - html , js (0) | 2024.08.18 |
[SpringBoot] WebSocket 채팅방 구현(1) - 구현 화면 (0) | 2024.08.17 |
[SpringBoot] 메뉴 계층형 구조 만들기(CheckBox, 전체 선택/해제) (0) | 2024.07.31 |
[SpringBoot] DataTable 이용하여 추가,수정,삭제 구현하기 (0) | 2024.07.26 |
댓글