diff --git a/src/main/java/com/softeer/podoarrival/event/controller/ArrivalEventSseController.java b/src/main/java/com/softeer/podoarrival/event/controller/ArrivalEventSseController.java new file mode 100644 index 0000000..bd8e1d5 --- /dev/null +++ b/src/main/java/com/softeer/podoarrival/event/controller/ArrivalEventSseController.java @@ -0,0 +1,25 @@ +package com.softeer.podoarrival.event.controller; + +import com.softeer.podoarrival.event.service.ArrivalEventService; +import io.swagger.v3.oas.annotations.Operation; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import reactor.core.publisher.Flux; + +@RestController +@RequiredArgsConstructor +@RequestMapping("/arrival") +@Slf4j +public class ArrivalEventSseController { + private final ArrivalEventService arrivalEventService; + + @GetMapping(value = "/time", produces = MediaType.TEXT_EVENT_STREAM_VALUE) + @Operation(summary = "선착순 서버시간 SSE Api") + public Flux streamLeftSecondsToEventTime() { + return arrivalEventService.streamLeftSecondsToEventTime(); + } +} diff --git a/src/main/java/com/softeer/podoarrival/event/service/ArrivalEventService.java b/src/main/java/com/softeer/podoarrival/event/service/ArrivalEventService.java index af9615b..d35e739 100644 --- a/src/main/java/com/softeer/podoarrival/event/service/ArrivalEventService.java +++ b/src/main/java/com/softeer/podoarrival/event/service/ArrivalEventService.java @@ -5,7 +5,10 @@ import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; +import reactor.core.publisher.Flux; +import java.time.Duration; +import java.time.LocalTime; import java.util.concurrent.CompletableFuture; @Slf4j @@ -15,7 +18,28 @@ public class ArrivalEventService { private final ArrivalEventReleaseService arrivalEventReleaseServiceRedisImpl; + /** + * 선착순 응모용 service. + * arrivalEventReleaseServiceJavaImpl과 arrivalEventReleaseServiceRedisImpl을 ArrivalEventReleaseService에 갈아끼우면 해당 방식으로 작동하게 된다. + * @param authInfo 사용자 jwt 토큰 정보 + * @return 선착순 응모 async method에 대한 CompletableFuture 타입 반환 + */ public CompletableFuture applyEvent(AuthInfo authInfo) { return arrivalEventReleaseServiceRedisImpl.applyEvent(authInfo); } + + /** + * SSE로 서버시간기준 이벤트 시작 시간까지 남은 시간을 전송 + * @return sse로 전송하게되는 이벤트까지 남은 시간 + */ + public Flux streamLeftSecondsToEventTime() { + return Flux.concat( + Flux.just(0L), // Emit initial value immediately + Flux.interval(Duration.ofSeconds(20))) + .map(sequence -> { + LocalTime startTime = ArrivalEventReleaseServiceJavaImpl.getStartTime(); + long seconds = Duration.between(LocalTime.now(), startTime).getSeconds(); + return Math.max(seconds, 0); + }); + } }