서버 전송 이벤트(Server-Sent Events, SSE) 및 웹소켓
1. 서버 전송 이벤트(SSE)란?
- 정의: SSE는 클라이언트와 서버 간에 한 방향 통신을 제공하는 웹 표준입니다.
- 기능: 서버가 클라이언트에게 새로운 데이터가 있을 때마다 푸시할 수 있습니다.
2. 웹소켓이란?
- 정의: 웹소켓은 클라이언트와 서버 간의 양방향 통신을 제공합니다.
- 적용: 실시간 상호작용이 필요한 애플리케이션에 적합합니다.
3. Spring Boot에서 SSE 구현
- Spring WebFlux 사용: 비동기 처리와 백프레셔 관리에 유용합니다.
- Spring MVC 사용:
SseEmitter
를 사용하여 SSE 구현 가능합니다.
4. WebFlux 구현 예시
public class Notification {
private final int id;
private final String content;
public Notification(int id, String content) {
this.id = id;
this.content = content;
}
// getters ...
}
import org.springframework.http.codec.ServerSentEvent;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Flux;
import java.time.Duration;
import java.util.stream.Stream;
@RestController
public class SseController {
private List<Notification> notificationList = new ArrayList<>();
@GetMapping("/sse/notifications")
public Flux<ServerSentEvent<Notification>> getNotificationStream() {
return Flux.fromStream(Stream.generate(() -> {
Notification notification = getLatestNotification(); // 구현 필요
return ServerSentEvent.<Notification>builder()
.id(String.valueOf(notification.getId()))
.event("notification-event")
.data(notification)
.build();
})).delayElements(Duration.ofSeconds(1));
}
}
5. WebMVC 구현 예시
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@RestController
public class SseController {
private final ExecutorService nonBlockingService = Executors.newCachedThreadPool();
@GetMapping(path = "/sse/notifications", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public SseEmitter pushSseNotifications() {
SseEmitter emitter = new SseEmitter();
nonBlockingService.execute(() -> {
try {
for (int i = 0; i < 500; i++) {
Notification notification = getLatestNotification(); // 구현 필요
emitter.send(notification);
Thread.sleep(1000);
}
emitter.complete();
} catch (Exception ex) {
emitter.completeWithError(ex);
}
});
return emitter;
}
}
6. 자원 사용량에 관한 고려 사항
- 웹소켓: 양방향 연결, 상태 유지 필요로 인해 더 많은 메모리와 CPU 사용.
- SSE: 단방향 연결로 인해 상대적으로 적은 메모리와 CPU 사용.
- 성능 테스트: 성능 테스트와 벤치마킹을 통해 선택해야 합니다.
중요: SSE와 웹소켓은 각각 다른 목적과 사용 사례에 적합하게 설계되었습니다. 실제 시나리오에 따라 적절한 기술을 선택해야 합니다.
댓글
댓글 쓰기