// 1. 채팅 li 컴포넌트 Key 중복 문제 해결
// 1-1. key에 메시지 내용을 쓰고 있었는데, 동일한 사용자가 들어왔다 나갔다를 반복하면
// 메시지 로그 상태에 동일한 형태의 '나갔습니다' '들어왔습니다'가 쌓여서 문제를 일으키고 있었음
// 1-2. 따라서 메시지에 new Date().toLocaleTimeString()을 추가해서 해결을 시도
// 근데 이러면 빠르게 같은 내용의 메시지를 보낼 때 key의 중복을 막지 못한다.
// 1-3. 서버에서 메시지의 id를 부여하게 하기
// 서버에 messageIdGenerator를 생성하고, id를 부여해 해결
// 프로젝트에서는 message 객체가 id를 갖게 하는 식으로 해결될듯
// 2. unsubscribe할 때 undefined 없애는 방법 찾기 (뭐가 undefined인건지 찾아보기)
// 2-1. 문제는 connected to server undefined
// CONNECTED frame에는 헤더가 포함되어 있는데, 없는 경우 undefined로 표시되고,
// 무시할 수 있는? 문제라는 공식 디렉터?의 피드백이 있음
// 3. 브라우저를 종료했을 때에도 접속 종료되게 하기
// 3-1. 이론적으로는...
// 클라이언트가 서버와 연결할 때 세션 정보를 보내고
// 서버는 등록된 세션을 주기적으로 health check해서
// 세션이 응답이 없으면 연결을 끊는다. 식으로 하면 될 것 같은데
// 딱 정리된 글이 없네...
// 3-2. utils에 WebSocketEventListener를 정의
// 메서드로 handleWebSocketConnectListener와 handleWebSocketDisconnectListener를 정의
// 인자로는 SessionConnectedEvent/SessionDisconnectedEvent를 각각 받고
// StompHeaderAccesor.wrap(event.getMessage())로 세션 정보를 알 수 있음
// 그리고 접속 종료는 연결을 직접 종료하거나, 브라우저를 직접 종료하는 것 둘 다
// SessionDisconnectedEvent가 발생하는 것이 확인되었음
// 3-3. 그러면 다시 Repository를 정의하고, 방 별로 Sessions를 관리해서
// 접속이 종료되는 경우에 그 Sessions에 들어 있는 각 session 들에게 서버에서 메시지를 쏘면 될 것 같음?
// SessionConnectedEvent에서 연결된 session을 식별할 수 있는 정보는 sessionId뿐인 것 같다.
// 하지만 그것만으로는 어느 Room에 접속하게 할지 식별이 안 된다.
// Authorization에 Username을 같이 담아서 전송하면 될까?
// 강제 종료 시 메시지 보내겠다고 로직이 바뀌는게 맞나?
// 3-4. 이 이슈에 너무 많은 시간을 쓰고 있다.
// 정리하자면 두 가지 방법 중 하나로 해보고 싶었다.
// - 서버에서 heartbeat를 보내서 클라이언트가 응답하면 ㅇㅋ, 응답 없으면 연결 끊고 메시징
// - 이 방법에서 모르겠는 점은 heartbeat를 클라이언트에서 어떻게 받는지, 서버에는 다시 어떻게 보내는지,
// 어떻게 연결을 끊을 것인지와, 끊었다는 메시지는 다른 session들에게 어떻게 보낼 것인지.
// - 연결 이벤트, 종료 이벤트 때 session을 확인해서 같이 있는 session들한테 메시지 쏘기
// - 이 방법에서 모르겠는 점은 header에서 받아온 session만으로는
// 어떤 방의 Sessions에 넣어줘야 하는지 모르겠다는 점이랑
// 종료 이벤트가 발생했을 때 어떤 방의 Sessions에서 찾아서 제거하고
// 그 Sessions의 세션들에게 메시지를 보낼 것인지.
// 3-5. window를 이용
// window에 Event Listener를 주입
// beforeunload 이름으로 window를 닫기 전에, 연결되어 있을 경우 disconnect를 수행
// 이 방식으로 해결
// 컴포넌트가 unmount될 때 실행시켜보자는 데에서 착안했으나,
// 화면 자체를 종료하는 것이 unmount로 이어지지는 않아 useEffect를 사용하지는 못했음
// cf. MessageController에서 사용할 수 있는 @MessageExceptionHandler라는 게 있다.
// 어떤 상황에서 에러가 발생하는지, 클라이언트에서 에러를 어떻게 처리해야 할지 아직은 모르겠다.
// 4. 사용자 입장, 메시지 전송, 사용자 퇴장을 모두 다른 요청으로 전송시키고,
// 서버의 Controller에서 구분하게 하기
// - 요청 주소를 모두 다르게 전송하고, Controller에서 응답을 받는 주소에 차이를 둠