📌 초기화 (initialize)
public void initialize(ChatPanel view, Long userId) {
this.chatView = view;
// Service → Controller 리스너 등록
chatService.initialize(userId, this::handleIncomingMessage);
userStateService.setUserListListener(this::handleUserListUpdate);
// View → Controller 이벤트 연결
view.setOnSendMessage(this::onSendButtonClick);
view.setOnSendWhisper(this::onWhisperButtonClick);
view.setOnDisconnect(this::onDisconnect);
view.setOnJoin(this::onJoinButtonClick);
}
- 서비스 → 컨트롤러:
- chatService.initialize() → 서버 연결 및 메시지 수신 시 handleIncomingMessage 실행.
- userStateService.setUserListListener() → 유저 목록 갱신 시 handleUserListUpdate 실행.
- 뷰 → 컨트롤러:
- UI에서 버튼 클릭 이벤트 발생 시 컨트롤러 메서드(onSendButtonClick, onWhisperButtonClick, onDisconnect, onJoinButtonClick) 실행.
📌 이벤트 핸들러 (View → Service)
1. 입장 버튼
public void onJoinButtonClick() {
chatService.joinChatRoom(); // 네트워크 구독 + JOIN 요청
chatView.addSystemMessage("Chatroom Join!");
}
- 유저가 "입장" 버튼을 누르면 채팅방에 들어가고, 시스템 메시지를 뷰에 표시.
2. 메시지 전송 버튼
public void onSendButtonClick(String text) {
if (text == null || text.trim().isEmpty()) return;
String trimmed = text.trim();
if (trimmed.startsWith("/w ")) {
handleWhisperCommand(trimmed); // 귓속말 처리
} else {
chatService.sendPublicMessage(trimmed); // 전체 채팅
}
}
- /w로 시작하면 귓속말, 아니면 전체 채팅으로 처리.
3. 귓속말 처리
private void handleWhisperCommand(String command) {
String[] parts = command.substring(3).split(" ", 2);
if (parts.length < 2) { showError("귓속말 형식: /w 받는사람 메시지"); return; }
String recipientName = parts[0].trim();
String message = parts[1].trim();
if (message.isEmpty()) { showError("메시지 내용을 입력해주세요."); return; }
Long recipientId = userStateService.getUserIdByName(recipientName);
if (recipientId == null) { showError("사용자를 찾을 수 없습니다: " + recipientName); return; }
if (!userStateService.isUserActive(recipientName)) {
showError(recipientName + "님은 현재 접속 중이 아닙니다."); return;
}
chatService.sendWhisper(recipientId, message);
}
- /w 받는사람 메시지 형식 파싱
- 유저 존재 여부 및 접속 여부 확인
- recipientName → recipientId 변환 후 chatService.sendWhisper() 호출
4. 연결 종료
public void onDisconnect() {
chatService.disconnect();
//chatView.close();
}
- 서버 연결 종료.
📌 이벤트 핸들러 (Service → View)
메시지 수신 처리
private void handleIncomingMessage(ChatMessageResponse message) {
switch (message.getType()) {
case "CHAT":
chatView.addPublicMessage(...);
break;
case "WHISPER":
chatView.addWhisperMessage(...);
break;
case "JOIN":
case "LEAVE":
chatView.addSystemMessage(message.getContent());
break;
}
}
- 서버에서 받은 메시지 타입에 따라 뷰에 표시:
- CHAT → 일반 메시지
- WHISPER → 귓속말 (특별 표시)
- JOIN/LEAVE → 시스템 메시지
유저 목록 갱신
private void handleUserListUpdate(Set<String> users) {
//chatView.updateUserList(users);
}
- 접속자 목록이 갱신되면 뷰에 반영 (현재는 주석 처리).
📌 showError
private void showError(String content) {
//chatView.showError(string);
}
- 에러 메시지를 뷰에 표시하는 메서드 (아직 구현 안 됨).
✅ 요약
- ChatController는 중간 제어자로서 View와 Service를 연결.
- View 이벤트 → Controller 메서드 → Service 호출.
- Service 이벤트 → Controller 메서드 → View 업데이트.
- 귓속말 처리 시 이름을 ID로 변환하는 이유는 서버가 ID 기반으로 유저를 식별하기 때문.
메시지 전송/받기 이벤트 진행 과정
1. [Controller → ChatService]
chatService.initialize(userId, this::handleIncomingMessage)
💡 Controller의 handleIncomingMessage() 메서드를 ChatService에 등록
2. [Controller → UserStateService]
userStateService.setUserListListener(this::handleUserListUpdate)
💡 Controller의 handleUserListUpdate() 메서드를 UserStateService에 등록
3. [Controller → View]
view.setOnSendMessage(this::onSendButtonClick)
💡 Controller의 onSendButtonClick() 메서드를 View에 등록
4. [ChatService → Network]
networkService.connect(url, this::onConnected, this::onError)
networkService.connect(url, this::onConnected, this::onError)
💡 ChatService의 onConnected() 메서드를 Network에 등록
5. [ChatService (onConnected 실행됨)]
networkService.subscribe("/topic/public", this::handlePublicMessage)
💡 ChatService의 handlePublicMessage() 메서드를 구독 핸들러로 등록
📌 이벤트 흐름 단계별 설명
1. 구독(Subscribe) 등록
networkService.subscribe("/topic/public", this::handlePublicMessage);
- 클라이언트가 특정 채널(/topic/public)을 구독합니다.
- 이때 this::handlePublicMessage라는 콜백 함수를 등록합니다.
- 의미: "이 채널에서 메시지가 오면 handlePublicMessage를 실행해라."
2. 서버에서 메시지 발행(Publish)
- 다른 사용자가 메시지를 보내면 서버(STOMP broker)가 해당 채널에 메시지를 발행합니다.
- 예: /topic/public으로 JSON 메시지 전송.
3. 클라이언트가 메시지 수신
- STOMP 클라이언트(StompSession)는 구독한 채널을 계속 듣고 있습니다.
- 메시지가 도착하면 내부적으로 이벤트가 발생합니다.
- NetworkService 구현체(StompNetworkService)가 이 이벤트를 감지하고, 등록된 콜백을 호출합니다.
=> 네트워크에서 구독해놓고, 그 경로로 메시지 들어오면 실행할 함수(chat서비스 함수)를 등록해준다.
들어오면 해당 서비스 함수에서 이벤트에 있는 함수들을 실행하여(controller에서 등록) view에 update.
'프로젝트' 카테고리의 다른 글
| 자프실 프로젝트 7 - 코드 리팩토링 (0) | 2025.12.06 |
|---|---|
| 자바프로젝트-5 클라이언트 시작! ChatService, userService (0) | 2025.12.06 |
| 자바 프로젝트-4 클라이언트 시작! stomp서버 연결하기 (0) | 2025.12.05 |
| 자프실 프로젝트-3 (0) | 2025.11.29 |
| 자프실 프로젝트-1 (0) | 2025.11.29 |