SseEmitter (Spring)
Spring Framework์์ SseEmitter
๋ ์๋ฒ์์ ํด๋ผ์ด์ธํธ๋ก Server-Sent Events(SSE)๋ฅผ ๋ณด๋ด๊ธฐ ์ํ ๊ฐ์ฒด์
๋๋ค. ์๋ฒ์์ ํด๋ผ์ด์ธํธ๋ก ์ค์๊ฐ ์
๋ฐ์ดํธ๋ฅผ ์ ์กํ๋ ๋ฐ ์ฌ์ฉ๋๋ ์๋ฒ ์ ์ก ์ด๋ฒคํธ(Server-Sent Events, SSE)๋ฅผ ๋ณด๋ด๊ธฐ ์ํ ResponseBodyEmitter
์ ํน์ ๋ฒ์ ์ด๋ค.
์ฝ๋ ์์ฝ
์๋ต ํ์ฅ:
extendResponse(ServerHttpResponse outputMessage)
:ResponseBodyEmitter
์์ ์ค๋ฒ๋ผ์ด๋ํ ๋ฉ์๋๋ก SSE์ ๋ง๊ฒ ์๋ฒ ์๋ต์ ์ปค์คํฐ๋ง์ด์ฆํฉ๋๋ค.Content-Type
์text/event-stream
์ผ๋ก ์ค์ ํฉ๋๋ค(๋ง์ฝ ์์ง ์ค์ ๋์ง ์์๋ค๋ฉด).
์ด๋ฒคํธ ๋ฐ์ก:
send(Object object)
: ๊ฐ์ฒด๋ฅผ ๋จ์ผ SSE "data" ๋ผ์ธ์ผ๋ก ์ ์กํฉ๋๋ค.send(Object object, @Nullable MediaType mediaType)
: ์ง์ ๋MediaType
์ ๊ฐ์ง ๊ฐ์ฒด๋ฅผ ์ ์กํ์ฌ ๋ฉ์์ง ์ปจ๋ฒํฐ ์ ํ ์ ์ปจํ ์ธ ํ์์ ๊ฐ๋ฅํ๊ฒ ํฉ๋๋ค.send(SseEventBuilder builder)
: id, ์ด๋ฒคํธ ์ด๋ฆ, ์ฝ๋ฉํธ ๋ฐ/๋๋ ์ฌ์ฐ๊ฒฐ ์๊ฐ๊ณผ ๋ฐ์ดํฐ๋ฅผ ํฌํจํ๋ ๋ณต์กํ SSE ์ด๋ฒคํธ๋ฅผ ์ ์กํ ์ ์์ต๋๋ค.
์ด๋ฒคํธ ๋น๋ฉ:
event()
:SseEventBuilderImpl
์ธ์คํด์ค๋ฅผ ๋ฐํํ๋ ์ ์ ๋ฉ์๋์ ๋๋ค.SseEventBuilderImpl
์ ๋ด๋ถ ํด๋์ค๋กSseEventBuilder
์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํฉ๋๋ค.
SseEventBuilder:
SseEmitter
ํด๋์ค ๋ด๋ถ์ ์ธํฐํ์ด์ค๋ก, SSE ์ด๋ฒคํธ๋ฅผ ๊ตฌ์ถํ๊ธฐ ์ํ ๋ฉ์๋๋ฅผ ์ ์ํฉ๋๋ค. ์๋ฅผ ๋ค์ดid
,name
,reconnectTime
,comment
,data
๋ฑ์ ๋ฉ์๋๊ฐ ์์ต๋๋ค.
SseEventBuilderImpl:
SseEventBuilder
์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํ๋ ๋ด๋ถ private static ํด๋์ค์ ๋๋ค. SSE ํ์์ ๋ฌธ์์ด์ ๊ตฌ์ฑํ๊ธฐ ์ํดStringBuilder
๋ฅผ ์ฌ์ฉํ๊ณ ์ ์กํ ๋ฐ์ดํฐ๋ฅผ ๋ด๋Set<DataWithMediaType>
๋ฅผ ์ฌ์ฉํฉ๋๋ค.
DataWithMediaType:
์ ์ก๋ ๊ฐ์ฒด์ ๊ทธ
MediaType
์ ์ฐ๊ด์ํค๋ ๊ฐ๋จํ ์ปจํ ์ด๋ ํด๋์ค๋ก ๋ณด์ ๋๋ค. ๋ด๋ถ์ ์ผ๋กSseEventBuilderImpl
์ ์ํด ์ฌ์ฉ๋ฉ๋๋ค.
send(SseEventBuilder builder)
๋ฉ์๋์์ synchronized
๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ ๋ฐ์ดํฐ๊ฐ ์ค๋ ๋ ์์ ํ ๋ฐฉ์์ผ๋ก ์ ์ก๋๋๋ก ๋ณด์ฅํฉ๋๋ค. ์๋ฒ ์ ์ก ์ด๋ฒคํธ๋ ์ผ๋ฐ์ ์ผ๋ก ์๋ฒ๊ฐ ์ค์๊ฐ์ผ๋ก ์
๋ฐ์ดํธ๋ฅผ ํด๋ผ์ด์ธํธ ๋ธ๋ผ์ฐ์ ๋ก ํธ์ํด์ผ ํ๋ ์ ํ๋ฆฌ์ผ์ด์
, ์๋ฅผ ๋ค์ด ๋์๋ณด๋ ๋๋ ์ค์๊ฐ์ผ๋ก ์
๋ฐ์ดํธ๋๋ ํผ๋์์ ์ฌ์ฉ๋ฉ๋๋ค.
์์
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.http.MediaType;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
@Controller
@RequestMapping("/sse")
public class SseController {
@GetMapping(value = "/stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public SseEmitter streamSseMvc() {
SseEmitter emitter = new SseEmitter();
// ์๋ก์ด ์ค๋ ๋์์ ๋น๋๊ธฐ๋ก ์ฒ๋ฆฌ
Executors.newSingleThreadExecutor().execute(() -> {
try {
for (int i = 0; i < 10; i++) {
// ๋ฐ์ดํฐ๋ฅผ ์ ์กํ๊ธฐ ์ ์ ์๋ฒ์์ ๋ฐ์ดํฐ๋ฅผ ์์ฑํ๊ฑฐ๋ ๊ฒ์ํฉ๋๋ค.
Thread.sleep(1000);
emitter.send("/sse/stream - " + LocalTime.now().toString());
}
emitter.complete();
} catch (IOException | InterruptedException e) {
emitter.completeWithError(e);
}
});
return emitter;
}
}
Last updated
Was this helpful?