본문 바로가기

WebSocket

아주 간단한 채팅 구현해보기 (WebSocket - 2)

Spring Boot로 만드는 WebSocket Tutorial - 채팅(1) — 이로운 개발하기 (tistory.com)

 

Spring Boot로 만드는 WebSocket Tutorial - 채팅(1)

소개 사용하는 PC에서 외부 메신저 설치가 불가능해 필요에 의해 만들어본 WebSocket 어플리케이션입니다. 간단하게 만들었기 때문에 WebSocket이 어떻게 돌아가는지 궁금하신 분들이나 실제로 저와

stir.tistory.com

 

WebSocketConfig

@Configuration
@RequiredArgsConstructor
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {

    private final ChatHandler chatHandler;

    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
        // "/ws/chat" 엔드포인트에서 WebSocket 요청을 처리하도록 ChatHandler를 등록, 모든 출처에서의 연결을 허용
        registry.addHandler(chatHandler, "ws/chat").setAllowedOrigins("*");
    }
}

 

ChatHandler

@Component
public class ChatHandler extends TextWebSocketHandler {

    //정적 LinkedHashSet. 활성 WebSocket의 세션을 추적하는데 사용
    private static LinkedHashSet<WebSocketSession> numSet = new LinkedHashSet<>();

    //들어오는 텍스트 메시지(유저)를 처리
    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        //세션 수가 3 이상인 경우 가장 오래된 세션에 메시지를 보낸 후 해당 세션 제거
        if (numSet.size() >= 3) {
            WebSocketSession oldSession = numSet.iterator().next();
            oldSession.sendMessage(new TextMessage("채팅이 종료되었습니다."));
            numSet.remove(numSet.iterator().next());
        }

        boolean isSessionAlive = false;

        for (WebSocketSession sess : numSet) {
            if (sess.getId().equals(session.getId())) {
                isSessionAlive = true;
            }
        }
        if (isSessionAlive) {
            for (WebSocketSession sess : numSet) {
                sess.sendMessage(message);
            }
        }
    }

    //연결이 설정되면 새로운 웹소켓 세션을 numSet에 추가
    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        numSet.add(session);
    }

    //닫힌 웹소켓 세션을 numSet에서 제거
    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
        numSet.remove(session);
    }
}

 

ChatController

@Controller
public class ChatController {

    @GetMapping("/")
    public String index() {
        return "error";
    }

    @GetMapping("/{id}")
    public String chattingRoom(@PathVariable String id, HttpSession session, Model model) {
        if (id.equals("guest")) {
            model.addAttribute("name", "guest");
        } else if (id.equals("master")) {
            model.addAttribute("name", "master");
        } else if (id.equals("loose")) {
            model.addAttribute("name", "loose");
        } else {
            return "error";
        }
        return "chattingRoom";
    }
}

 

코드의 작동

  • WebSocketConfig
    • @EnableWebSocket 어노테이션으로 WebSocket 활성화를 설정하고, "registerWebSocketHandlers" 메소드에서 WebSocket 핸들러(chatHandler)를 /ws/chat 엔드포인트에 등록한다.
  • ChatHandler
    • WebSocket 연결이 수립될 때(afterConnectionEstablished) 새로운 WebSocket 세션을 numSet에 추가한다.
    • 클라이언트 메시지가 수신되면(handleTextMessage) 현재 세션이 활성 상태인지 확인하고 모든 세션에 메시지를 브로드 캐스트한다.
    • WebSocket 연결이 종료될때(afterConnectionClosed)종료 된 세션을 numSet에서 제거한다.
  • ChatController
    • 클라이언트의 엔드포인트 접근마다의 에러 혹은 반환 제어
  • WebSocket 통신
    • 클라이언트가 "{id}" 페이지에 접근하면 WebSocket 연결이 수립
    • ChatHandler가 연결된 엔드포인트에서 WebSocket 메시지를 처리하고, 메시지가 수신되면 모든 연결된 세션에 메시지를 전송

 

 

'WebSocket' 카테고리의 다른 글

웹 소켓(Web Socket)이란?? (WebSocket - 1)  (0) 2024.01.08