실무에서 Spring Boot를 사용하여 외부 API와 연동하는 경우가 많습니다. 특히, 챗봇 API와 같은 경우 서버에서 실시간으로 응답을 받아 클라이언트에 스트리밍해야 하는 요구가 발생합니다.
이번 포스팅에서는 OkHttp3를 활용하여 외부 API를 호출하고, Server-Sent Events(SSE)를 이용해 클라이언트에 실시간으로 데이터를 전달하는 방법을 정리해 보았습니다.
1. SSE(Server-Sent Events)란?
Server-Sent Events(SSE)는 HTTP를 통해 서버에서 클라이언트로 단방향 스트리밍을 제공하는 기술입니다. WebSocket과 달리 클라이언트가 서버에 연결을 요청한 후, 서버가 지속적으로 데이터를 전송할 수 있습니다. SSE는 주로 실시간 데이터 스트리밍 (예: 주식 정보, 채팅, 알림 등)에 활용됩니다.
2. Spring Boot에서 SSE 활용하기
Spring Boot에서는 Flux<String>
을 반환하여 SSE 스트림을 손쉽게 구현할 수 있습니다.
먼저, SSE 기능을 활용하기 위해 WebFlux 의존성을 추가해야 합니다.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
3. OkHttp3을 사용한 외부 API 호출 및 SSE 변환
실무에서는 OkHttp3을 사용하여 외부 API를 호출한 후, 해당 응답을 SSE로 변환하는 요구가 자주 발생합니다.
아래 코드는 이미 구현된 API 호출 로직에서 얻은 okhttp3.Response
객체를 이용하여 SSE로 데이터를 전송하는 방법을 보여줍니다.
@RestController
public class ChatController {
@GetMapping(value = "/chat-stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public Flux<String> streamChatResponse(@RequestParam String message) {
Sinks.Many<String> sink = Sinks.many().unicast().onBackpressureBuffer();
Response response = callChatApi(message); // API 호출 로직
processResponse(response, sink);
return sink.asFlux();
}
private Response callChatApi(String message) {
return ChatApiClient.callApi(message); // 이미 구현된 API 호출 메서드
}
private void processResponse(Response response, Sinks.Many<String> sink) {
try (BufferedReader reader = new BufferedReader(new InputStreamReader(response.body().byteStream()))) {
String line;
while ((line = reader.readLine()) != null) {
sink.tryEmitNext("data: " + line + "\n");
}
} catch (Exception e) {
sink.tryEmitNext("Error reading response: " + e.getMessage());
} finally {
sink.tryEmitComplete();
}
}
}
4. 클라이언트에서 SSE 데이터 수신
클라이언트에서는 EventSource
API를 사용하여 SSE 데이터를 받을 수 있습니다.
const eventSource = new EventSource("http://localhost:8080/chat-stream?message=Hello");
eventSource.onmessage = (event) => {
console.log("Received:", event.data);
};
eventSource.onerror = (error) => {
console.error("SSE Error:", error);
eventSource.close();
};
5. 정리
- SSE는 서버에서 클라이언트로 실시간 데이터를 전송하는 효율적인 방법입니다.
- OkHttp3을 활용하여 외부 API 데이터를 받아온 후, 이를 SSE 스트림으로 변환하여 제공할 수 있습니다.
- Spring Boot에서 Flux<String>
을 반환하여 손쉽게 SSE를 구현할 수 있습니다.
- 클라이언트는 EventSource
를 이용해 SSE 데이터를 수신할 수 있습니다.
6. 추가 고려 사항
- 만약 스트리밍이 필요하지 않다면 단순 JSON 응답으로 변경할 수도 있습니다.
- 네트워크 문제로 인해 SSE 연결이 끊어질 수 있으므로 클라이언트 측에서 재연결 로직을 구현하는 것이 좋습니다.
- WebFlux를 활용하면 Spring MVC보다 더욱 효율적으로 비동기 처리를 할 수 있습니다.
Comments
Post a Comment