-
Notifications
You must be signed in to change notification settings - Fork 3
Feat: 메세지 알림 구현 #162
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feat: 메세지 알림 구현 #162
Conversation
lunarbae628
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
뭔가 어떻게 알림이 가는건지 로직을 잘 모르겠습니다 ㅠㅠ 설명부탁드려요
| @Query(""" | ||
| SELECT cr | ||
| FROM ChatRoom cr | ||
| JOIN cr.participants cp | ||
| LEFT JOIN cr.messages m | ||
| WHERE cp.participant.id = :memberId AND cp.isActive = true | ||
| GROUP BY cr | ||
| ORDER BY MAX(m.sendAt) DESC NULLS LAST | ||
| """) | ||
| List<ChatRoom> findAllRoomsByParticipantId(@Param("memberId") Long memberId); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
P4: 반영해도 좋고 넘어가도 좋습니다 (Approve)
추후에 채팅방에 마지막 메시지칼럼을 추가하여 메시지 생성/삭제 시 업데이트하면 이 쿼리가 간단해질 것 같은데 추후에 고려해봐도 좋을 것 같습니다!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
recentRoomId같은 느낌이군요. 그럼 chatRoom에서 마지막 메시지의 sendAt 칼럼을 저장하게 되는건가요??
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
네 일단 지금 생각나는 대안은 그렇습니다. lastSentAt칼럼을 업데이트하는 식을 생각했습니다!
뭐가 더 나을지는 생각을 좀 더 해보긴 해야겠지만요ㅎㅎ
lunarbae628
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
수고하셨습니다
LimKangHyun
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
따로 코드작성이 되었던게 아니었네요.
시큐리티를 타지 않게 하는 permitAll()이 핵심이군요 고생하셨습니다.
🛰️ Issue Number
#158
🪐 작업 내용
웹소켓 연결 강제 종료 문제
웹소켓 연결이
CloseStatus[1008, "This connection was established under an authenticated HTTP session that has ended."]라는 이유로 서버 측에서 강제 종료해버리는 사례가 간헐적으로 발생했는데스프링에서 등록된 WsServerContainer에서 웹소켓이 http로 handshake 시점에 securityContextHolder에 등록된 사용자가 존재 시
private final ConcurrentMap<String, Set<WsSession>> authenticatedSessions;위 맵에
httpSessionId -> (연결된 WsSession들)형태로 등록해서 http 세션이 종료될 때 연결된 웹소켓 세션들을 강제종료하는 코드를 확인했습니다. 그래서 웹소켓 연결 경로는 permitAll()로 열어놓고 jwtFilter 대신 websocketHandshakeInterceptor에서 토큰 검증을 하도록 했습니다. (securityContextHolder에 인증객체 등록을 피하기 위함)WebsocketHandshakeInterceptor에서 토큰 검증 후 인증 객체를 웹소켓 세션의 attribute에 넣어두면JwtHandshakeHandler가 attribute에서 꺼내서 웹소켓 세션 레벨의 인증 객체로 등록하고 그 후WebScoektChannelInterceptor가 stomp connect 단계에서 attribute에서 인증 객체를 꺼내 stomp 메시지 사용자(@MessageMapping의 Principle로 받는 객체)로 등록합니다.웹소켓 세션과 stomp 단계에서의 인증 객체 각각 별도로 주입해서 최대한 모든 요청들이 인증된 상태로 남게 했으니 인증에 문제가 될 일은 없다고 생각합니다!
글구 interceptor 단계에서 유효한 토큰이 아니면 handshake를 거부하고 useWebsocket.jsx의 onWebsocketClose 콜백을 통해 토큰 refresh를 요청합니다.
채팅방 메세지 알림
채팅방 헤더에 보면 종모양이 추가됐는데 저 종 임티를 토글하면 채팅방 새 메세지 수신 알림을 받을지 말지 결정할 수 있습니다. chatAlarm 데이터를 서버에서 저장하고 프론트에서 roomId에 따른 알림 여부를 전역적으로 context로 관리합니다.
일단 새 메세지가 수신되면 사이드바의 해당 채팅방에 빨간점이 뜸과 함께 목록에서 최상단으로 올리는데 이때 사용자가 해당 채팅방에 들어가있지 않고 알림 여부도 true이면(sideBar.jsx에서 판단) 브라우저 알림과 말왕 소리를 발생시킵니다. 브라우저 알림 요청 이벤트는 sideBar.jsx에서 발행하고 이 이벤트를 header.jsx에서 받아서 브라우저에 알림을 보내는 방식입니다!
그리고 알림이 계속 쌓이면 기존 알림을 덮어쓰는 방식으로 변경했습니다. 그리고 알림 배너를 클릭하면 메세지가 수신된 채팅방으로 이동함과 동시에 배너가 닫힙니다
사이드바 채팅방 목록 페이지네이션에서 스크롤 방식으로 변경
사이드바에서 페이지네이션 방식으로 채팅방 목록을 조회했는데 스크롤 방식으로 변경하고 모든 채팅방의 알림 상태를 프론트에서 가지고 있어야해서 모든 채팅방 list를 가져오는걸로 변경했습니다.
📚 Reference
현재 로컬에서 테스트했을 때 s3에 업로드된 이미지가 안보이는 문제가 발생합니다ㅜㅜ
✅ Check List