11package dsm.pick2024.infrastructure.sse
22
33import dsm.pick2024.infrastructure.sse.port.out.SseRegistryPort
4+ import org.apache.catalina.connector.ClientAbortException
45import org.slf4j.LoggerFactory
56import org.springframework.stereotype.Component
67import org.springframework.web.servlet.mvc.method.annotation.SseEmitter
8+ import java.io.IOException
79import java.util.UUID
810import java.util.concurrent.ConcurrentHashMap
911import java.util.concurrent.CopyOnWriteArrayList
@@ -17,10 +19,7 @@ class SseRegistry : SseRegistryPort {
1719 val emitter = SseEmitter (60 * 60 * 1000L * 2 ) // 2시간
1820 emitters.computeIfAbsent(userId) { CopyOnWriteArrayList () }.add(emitter)
1921
20- val cleanup = Runnable { remove(userId, emitter) }
21- emitter.onCompletion(cleanup)
22- emitter.onTimeout(cleanup)
23- emitter.onError { cleanup.run () }
22+ registerEmitterCallbacks(emitter, userId)
2423
2524 return emitter
2625 }
@@ -37,9 +36,42 @@ class SseRegistry : SseRegistryPort {
3736 try {
3837 emitter.send(SseEmitter .event().data(data ? : " ." ))
3938 } catch (e: Exception ) {
39+ if (isClientAbort(e)) {
40+ emitter.completeWithError(e)
41+ remove(userId, emitter)
42+ continue
43+ }
4044 logger.error(" User Event Send Failed ${e.message} " , e)
45+ emitter.completeWithError(e)
4146 remove(userId, emitter)
4247 }
4348 }
4449 }
50+
51+ override fun sendHeartbeat () {
52+ for (userId in emitters.keys) {
53+ sendToUser(userId, " heartbeat" )
54+ }
55+ }
56+
57+ // Broken pipe error인지 확인
58+ private fun isClientAbort (e : Exception ): Boolean {
59+ if (e is ClientAbortException ) return true
60+ val io = e as ? IOException
61+ val message = (io?.message ? : e.message).orEmpty()
62+ return message.contains(" Broken pipe" , ignoreCase = true )
63+ }
64+
65+ private fun registerEmitterCallbacks (emitter : SseEmitter , userId : UUID ) {
66+ val cleanup = Runnable { remove(userId, emitter) }
67+
68+ emitter.onCompletion(cleanup)
69+ emitter.onTimeout {
70+ emitter.complete()
71+ cleanup.run ()
72+ }
73+ emitter.onError {
74+ cleanup.run ()
75+ }
76+ }
4577}
0 commit comments