diff --git a/src/main/java/ddingdong/ddingdongBE/sse/api/SseConnectionApi.java b/src/main/java/ddingdong/ddingdongBE/sse/api/SseConnectionApi.java new file mode 100644 index 00000000..3fd1d2a6 --- /dev/null +++ b/src/main/java/ddingdong/ddingdongBE/sse/api/SseConnectionApi.java @@ -0,0 +1,27 @@ +package ddingdong.ddingdongBE.sse.api; + +import ddingdong.ddingdongBE.auth.PrincipalDetails; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.security.SecurityRequirement; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.security.core.annotation.AuthenticationPrincipal; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.servlet.mvc.method.annotation.SseEmitter; + +@Tag(name = "SSE", description = "SSE subscribe API") +@RequestMapping("/server/sse") +public interface SseConnectionApi { + + @Operation(summary = "SSE 구독") + @ApiResponse(responseCode = "200", description = "활동 보고서 전체 조회 성공") + @ResponseStatus(HttpStatus.OK) + @SecurityRequirement(name = "AccessToken") + @GetMapping(value = "/subscribe", produces = MediaType.TEXT_EVENT_STREAM_VALUE) + SseEmitter subscribe(@AuthenticationPrincipal PrincipalDetails principalDetails); + +} diff --git a/src/main/java/ddingdong/ddingdongBE/sse/controller/SseConnectionController.java b/src/main/java/ddingdong/ddingdongBE/sse/controller/SseConnectionController.java new file mode 100644 index 00000000..125b33d3 --- /dev/null +++ b/src/main/java/ddingdong/ddingdongBE/sse/controller/SseConnectionController.java @@ -0,0 +1,23 @@ +package ddingdong.ddingdongBE.sse.controller; + +import ddingdong.ddingdongBE.auth.PrincipalDetails; +import ddingdong.ddingdongBE.domain.user.entity.User; +import ddingdong.ddingdongBE.sse.api.SseConnectionApi; +import ddingdong.ddingdongBE.sse.service.SseConnectionService; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.servlet.mvc.method.annotation.SseEmitter; + +@RestController +@RequiredArgsConstructor +public class SseConnectionController implements SseConnectionApi { + + private final SseConnectionService sseConnectionService; + + @Override + public SseEmitter subscribe(PrincipalDetails principalDetails) { + User user = principalDetails.getUser(); + Long timeout = 60L * 1000; // 1분 (60초 * 1000밀리초) + return sseConnectionService.subscribe(user.getAuthId(), timeout); + } +} diff --git a/src/main/java/ddingdong/ddingdongBE/sse/service/SseConnectionService.java b/src/main/java/ddingdong/ddingdongBE/sse/service/SseConnectionService.java index f9720cc6..fdb62a1e 100644 --- a/src/main/java/ddingdong/ddingdongBE/sse/service/SseConnectionService.java +++ b/src/main/java/ddingdong/ddingdongBE/sse/service/SseConnectionService.java @@ -21,17 +21,13 @@ public SseEmitter subscribe(String id, Long timeout) { sseConnectionRepository.save(id, sseEmitter); // 연결 완료 콜백 - sseEmitter.onCompletion(() -> { - sseConnectionRepository.deleteById(id); - }); + sseEmitter.onCompletion(() -> sseConnectionRepository.deleteById(id)); // 연결 타임아웃 콜백 sseEmitter.onTimeout(sseEmitter::complete); // 연결 에러 콜백 - sseEmitter.onError((ex) -> { - sseConnectionRepository.deleteById(id); - }); + sseEmitter.onError((ex) -> sseConnectionRepository.deleteById(id)); try { sseEmitter.send(