개요
실시간 알림을 구현하는 과정에서 페이지 이동시 소켓 연결이 끊기는 이슈가 발생했습니다.
- 소켓 연결을 새로고침을 하거나 다른 페이지로 이동을 하면 끊기게 되있습니다.
- 이를 막기 위한 방법으로 새로고침 시 경고 창을 띄어주거나 방지하는 방법이 있지만
- 저희 서비스에서는 단순히 새로고침 뿐 아니라 페이지 전역에서 소켓 연결을 유지할 방법이 필요했습니다.
소켓 정보 DB저장
- 우선 저희 서비스에서 알림은 상품에 대한 구독으로부터 시작됩니다.
- 판매자는 상품을 등록했을 때, 소비자는 상품에 입찰을 걸었을 때 해당 상품에 구독하면서 알림 서비스를 지원합니다.
- 사용자는 소켓에 구독할 때마다 DB에 자신의 소켓 목록을 저장합니다.
- 모든 페이지에 접근할 때마다 자신의 소켓 연결 정보를 불러오며 재구독합니다.(연결 로직을 header.html에 작성)
소켓 구조 리팩토링
기존 소켓 구조
기존 구조의 문제점은 구독해야 할 소켓의 개수가 너무 많다는 문제였습니다.
- 판매자와 소비자의 알림을 구분하기 위해 또한 Item을 구분하기 위해 다음과 같은 구조를 이용했습니다.
item-1-seller, item1-buyer, item2-seller
- 단점으로는 연관된 상품의 개수가 늘어날수록 구독해야하는 소켓의 개수가 계속해서 증가하는 것이었습니다.
- 또한 item별 권한 별 소켓이 분리되면서 서버에서의 로직도 너무 복잡해졌습니다.
-> 메시지를 각각 다른 sub으로 발행되어야 하는 문제도 발생합니다. 주체가 아이템이 되어버립니다.
-> 확장성 저하
개인 소켓 구독
- 위와 같은 문제를 해결하기 위해 저희는 사용자는 개인 소켓만을 구독하고 특정 이벤트가 발생했을 때 대상자에게만 메시지를 pub하는 구조로 변경했습니다.
입찰, 댓글, 판매 완료 알림 흐름
- Http요청으로도 할 수 있었지만 WebSocket이 연결되있는 상태에서는 메시지를 발행하는 것이 더 효율적이라고 하여 입찰과 댓글이 등록되거나 판매 완료 처리가 되었을 때 알림 메시지를 발행하도록 설계했습니다.
- 서버에서는 메시지를 받아야하는 유저의 sub으로만 발행을 해주면 됩니다.(주체가 유저)
- 입찰 마감 같은경우에
는 Redis의 timeout에 의한 이벤트로 관리되기 때문에 별도의 흐름을 갖습니다.
'Project > Bidderown' 카테고리의 다른 글
페이징 처리 성능 개선(3) - Covering Index (0) | 2023.08.14 |
---|---|
페이징 처리 성능 개선(2) - Covering Index (0) | 2023.08.13 |
페이징 처리 성능 개선(1) - noOffset 적용 (0) | 2023.07.22 |