attlet / sns_project

코틀린 + spring boot 사이드 프로젝트
0 stars 0 forks source link

알림 기능 sse 구현 부분 리팩토링 #34

Closed attlet closed 1 week ago

attlet commented 1 week ago

emitter 를 저장하는 concurrentHashMap이 notificationService에 위치해있는데, 이는 레이어드 아키텍처에 있어 적절하지 않다고 판단.

db, 또는 메모리와 상호작용하는 레이어는 repository로 지정하고 있기에, emitterMap에 put, remove등 sse관련 로직을 SseRepository로 따로 빼는 것으로 결정

attlet commented 1 week ago

기존 notificationService

/**
 * 연결된 클라이언트들을 저장하는 자료구조
 * 추후 고도화 필요
 */
private val emittersMap = ConcurrentHashMap<Long, SseEmitter>()

 /**
 * sse 구독 신청
 *
 * @param userId
 * @return
 */
override fun subscribe(userId : Long) : SseEmitter{
    val emitter = SseEmitter(60 * 1000L)  //60초 연결

    emittersMap[userId] = emitter

    emitter.onCompletion { emittersMap.remove(userId)}
    emitter.onTimeout{ emittersMap.remove(userId)}
    emitter.onError { emittersMap.remove(userId) }

    return emitter
}

/**
 * userId를 가진 member에게 notification 전송하는 메서드
 *
 * @param userId
 * @param notification
 */
override fun sendNotificationToClient(userId: Long, notification: Notification) {
    val emitter = emittersMap[userId] ?: return  //추후 처리하는 로직 작성 필요

    try{
        emitter.send(SseEmitter
            .event()
            .name("notification")
            .data(notification))
    } catch (e : IOException){
        emittersMap.remove(userId)   //추후 체크 필요
    }
}

}`

여기서 emitter Map과 관련 로직을 SseRepository로 이전.

attlet commented 1 week ago
/**
 * 연결된 클라이언트들을 저장하는 자료구조
 * 추후 고도화 필요
 */
private val emittersMap = ConcurrentHashMap<Long, SseEmitter>()

fun save(userId: Long, emitter: SseEmitter) {
    emittersMap[userId] = emitter
}

fun get(userId: Long): SseEmitter? {
    return emittersMap[userId]
}

fun remove(userId: Long) {
    emittersMap.remove(userId)
}

fun contains(userId: Long): Boolean {
    return emittersMap.containsKey(userId)
}

SseRepository로 분리 완료.