@@ -119,19 +119,24 @@ public SseEmitter subscribeToWeather(double lat, double lng) {
119119 lng , RADIUS );
120120 final String key = gridResponse .getGridX () + "," + gridResponse .getGridY ();
121121 final SseEmitter emitter = new SseEmitter (TIMEOUT );
122- emitters . put (key , emitter );
122+ registerEmitter (key , emitter );
123123
124- emitter .onCompletion (() -> emitters .remove (key ));
125- emitter .onTimeout (() -> {
126- emitters .remove (key );
127- emitter .complete ();
128- });
129124 // 구독 시 즉시 최신 날씨 정보 전송
130125 sendWeatherUpdate (emitter , gridResponse .getGridX (), gridResponse .getGridY ());
131126
132127 return emitter ;
133128 }
134129
130+ private void registerEmitter (String key , SseEmitter emitter ) {
131+ emitters .put (key , emitter );
132+ emitter .onCompletion (() -> emitters .remove (key ));
133+ emitter .onTimeout (() -> {
134+ log .info ("SSE 타임아웃 발생: {}" , key );
135+ emitter .complete ();
136+ emitters .remove (key );
137+ });
138+ }
139+
135140 @ Scheduled (fixedRate = 60000 ) // 1분마다 실행
136141 public void sendWeatherUpdates () {
137142 emitters .forEach ((key , emitter ) -> {
@@ -148,11 +153,23 @@ private void sendWeatherUpdate(SseEmitter emitter, double nx, double ny) {
148153 try {
149154 emitter .send (SseEmitter .event ().name (WEATHER_EVENT_NAME ).data (weatherData ));
150155 } catch (IOException e ) {
151- log .error ("날씨 데이터 전송 실패" , e );
156+ log .warn ("SSE 연결 끊김: 좌표({},{})" , nx , ny );
157+ emitter .complete ();
158+ removeEmitter (nx , ny );
159+ } catch (BusinessException e ) {
160+ log .error ("날씨 데이터 응답 오류: {}" , e .getMessage ());
161+ } catch (Exception e ) {
162+ log .error ("알 수 없는 오류" , e );
152163 emitter .completeWithError (e );
164+ removeEmitter (nx , ny );
153165 }
154166 }
155167
168+ private void removeEmitter (double nx , double ny ) {
169+ final String key = nx + "," + ny ;
170+ emitters .remove (key );
171+ }
172+
156173 private String getStringCell (Cell cell ) {
157174 if (cell == null ) {
158175 return null ;
0 commit comments