Skip to content

Commit fed9668

Browse files
committed
✨ feat: SSE 하트비트 추가
1 parent 7174f8e commit fed9668

File tree

3 files changed

+19
-9
lines changed

3 files changed

+19
-9
lines changed

backend/src/main/java/io/f1/backend/domain/game/app/GameService.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ public class GameService {
5959
private final RoomRepository roomRepository;
6060
private final ApplicationEventPublisher eventPublisher;
6161

62-
@DistributedLock(prefix = "room", key = "#roomId", waitTime = 0)
62+
@DistributedLock(prefix = "room", key = "#roomId")
6363
public void gameStart(Long roomId, UserPrincipal principal) {
6464

6565
String destination = getDestination(roomId);

backend/src/main/java/io/f1/backend/domain/game/sse/app/SseService.java

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,28 +9,30 @@
99
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
1010

1111
import java.io.IOException;
12+
import java.util.concurrent.Executors;
13+
import java.util.concurrent.ScheduledExecutorService;
14+
import java.util.concurrent.TimeUnit;
1215

1316
@Service
1417
@RequiredArgsConstructor
1518
public class SseService {
1619

1720
private final SseEmitterRepository emitterRepository;
21+
private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
1822

1923
public SseEmitter subscribe() {
20-
SseEmitter emitter = new SseEmitter(1_800_000L);
24+
SseEmitter emitter = new SseEmitter(5_000L);
2125
emitterRepository.save(emitter);
2226

2327
try {
24-
// emitter 정상 전송확인 메시지
2528
emitter.send(SseEmitter.event().name("connect").data("connected"));
29+
startHeartBeat(emitter);
2630
} catch (IOException e) {
27-
// emitter send() 호출 시 예외 처리
28-
emitterRepository.remove(emitter);
31+
emitter.completeWithError(e);
2932
}
3033
return emitter;
3134
}
3235

33-
// 로비로 SSE 메시지를 쏘기위한 메서드
3436
public <T> void notifyLobbyUpdate(LobbySseEvent<T> event) {
3537
for (SseEmitter emitter : emitterRepository.getAll()) {
3638
try {
@@ -40,4 +42,14 @@ public <T> void notifyLobbyUpdate(LobbySseEvent<T> event) {
4042
}
4143
}
4244
}
45+
46+
private void startHeartBeat(SseEmitter emitter) {
47+
scheduler.scheduleAtFixedRate(() -> {
48+
try {
49+
emitter.send(SseEmitter.event().name("heartbeat").data("sse-alive"));
50+
} catch (IOException e) {
51+
emitterRepository.remove(emitter);
52+
}
53+
}, 5, 60, TimeUnit.SECONDS);
54+
}
4355
}

backend/src/main/java/io/f1/backend/domain/game/sse/store/SseEmitterRepository.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,18 +13,16 @@ public class SseEmitterRepository {
1313

1414
public void save(SseEmitter emitter) {
1515
emitters.add(emitter);
16-
// 연결종료 객체정리
16+
1717
emitter.onCompletion(() -> emitters.remove(emitter));
1818
emitter.onTimeout(() -> emitters.remove(emitter));
1919
emitter.onError(error -> emitters.remove(emitter));
2020
}
2121

22-
// 연결 종료 객체 정리
2322
public void remove(SseEmitter emitter) {
2423
emitters.remove(emitter);
2524
}
2625

27-
// 브로드캐스팅
2826
public List<SseEmitter> getAll() {
2927
return emitters;
3028
}

0 commit comments

Comments
 (0)