Mac에서 websocket채팅이 2번 보내지는 문제

Kim jisu·2025년 9월 8일
0

 Debugging Note

목록 보기
37/37

맥 한글 입력 중복 메시지 전송 문제 디버깅 노트

문제 요약

문제: 맥에서 한글로 채팅 입력 시 메시지가 중복으로 전송되는 현상
영향 범위: 맥OS 사용자의 채팅 기능
해결 상태: 완료


문제 분석

증상

  • 맥에서 한글 입력 후 Enter 키를 누르면 메시지가 2번 전송됨
  • 영문 입력 시에는 문제 없음
  • 다른 운영체제에서는 문제 없음

근본 원인

  1. IME (Input Method Editor) 처리 누락

    • 한글 입력 시 compositionstart/compositionend 이벤트 미처리
    • Enter 키가 한글 조합 완료와 메시지 전송을 동시에 트리거
  2. 이벤트 중복 처리

    • 기존 코드에서 composition 상태 확인 없음
    • 짧은 시간 내 중복 이벤트 방지 로직 부재

기존 코드 문제점

// chat.js:37-42 (수정 전)
document.addEventListener('keydown', (e) => {
    if (e.key === 'Enter' && !e.shiftKey && e.target.classList.contains('message-textarea')) {
        e.preventDefault();
        this.sendMessage(); // IME 상태 확인 없이 바로 전송
    }
});

해결 방법

1. Composition 상태 추적

// ChatInterface 생성자에 상태 변수 추가
constructor() {
    this.selectedRoomId = null;
    this.stompClient = null;
    this.currentUser = null;
    this.isComposing = false;      // IME 입력 상태
    this.lastSendTime = 0;         // 중복 방지용 타임스탬프
    
    this.init();
}

2. IME 이벤트 핸들러 추가

// Composition 이벤트 처리
document.addEventListener('compositionstart', (e) => {
    if (e.target.classList.contains('message-textarea')) {
        this.isComposing = true;
    }
});

document.addEventListener('compositionend', (e) => {
    if (e.target.classList.contains('message-textarea')) {
        this.isComposing = false;
    }
});

3. Enter 키 핸들러 개선

// 개선된 Enter 키 처리
document.addEventListener('keydown', (e) => {
    if (e.key === 'Enter' && !e.shiftKey && e.target.classList.contains('message-textarea')) {
        // IME 입력 중일 때는 메시지 전송 방지
        if (!this.isComposing) {
            e.preventDefault();
            this.sendMessage();
        }
    }
});

4. 중복 전송 방지 로직

async sendMessage() {
    const textarea = document.getElementById('messageInput');
    const message = textarea?.value.trim();
    
    if (!message || !this.selectedRoomId) {
        return;
    }
    
    // 디바운스 로직 - 500ms 내 중복 전송 방지
    const now = Date.now();
    if (now - this.lastSendTime < 500) {
        console.log('Duplicate message send prevented (debounced)');
        return;
    }
    
    // 추가 안전장치 - composition 상태 재확인
    if (this.isComposing) {
        console.log('Message send prevented: IME composition in progress');
        return;
    }
    
    this.lastSendTime = now;
    
    // 기존 전송 로직...
}

적용된 변경사항

파일: src/main/resources/static/js/chat.js

1. 생성자 수정 (라인 3-11)

  • isComposing 상태 플래그 추가
  • lastSendTime 디바운스용 타임스탬프 추가

2. 이벤트 바인딩 추가 (라인 38-60)

  • compositionstart 이벤트 핸들러
  • compositionend 이벤트 핸들러
  • 기존 keydown 핸들러에 composition 상태 검사 추가

3. sendMessage 메서드 개선 (라인 615-661)

  • 500ms 디바운스 로직 추가
  • composition 상태 재확인 로직 추가
  • 디버깅을 위한 콘솔 로그 추가

profile
Dreamer

0개의 댓글