<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>Streaming on Chanyeol Dev</title>
    <link>https://chanyeols.com/tags/streaming/</link>
    <description>Recent content in Streaming on Chanyeol Dev</description>
    <generator>Hugo</generator>
    <language>ko-kr</language>
    <lastBuildDate>Sat, 21 Mar 2026 14:30:00 +0900</lastBuildDate>
    <atom:link href="https://chanyeols.com/tags/streaming/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Spring WebFlux와 SSE로 구현하는 AI 스트리밍 API: 실시간 대화 경험 (5편)</title>
      <link>https://chanyeols.com/posts/spring-webflux-sse-ai-streaming-api/</link>
      <pubDate>Sat, 21 Mar 2026 14:30:00 +0900</pubDate>
      <guid>https://chanyeols.com/posts/spring-webflux-sse-ai-streaming-api/</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;[Dev-Fortune] 시리즈 다시보기&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://chanyeols.com/posts/spring-ai-ollama-chatbot-planning/&#34;&gt;1편: 기획부터 스택 선정까지&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://chanyeols.com/posts/ollama-spring-boot-local-llm-setup/&#34;&gt;2편: 로컬 LLM Ollama 연동&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://chanyeols.com/posts/spring-ai-rag-simplevectorstore-ingestion/&#34;&gt;3편: RAG와 Vector Store 구축&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://chanyeols.com/posts/prompt-engineering-ai-persona-tuning/&#34;&gt;4편: 프롬프트 엔지니어링 실전&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;1-서론-ai-답변-왜-기다리게-하나요&#34;&gt;1. 서론: AI 답변, 왜 기다리게 하나요?&lt;/h2&gt;
&lt;p&gt;사용자 경험(UX)을 위해 한 글자씩 타이핑하듯 보여주는 스트리밍 방식은 필수적입니다. 우리 프로젝트는 &lt;strong&gt;WebFlux&lt;/strong&gt;와 **SSE(Server-Sent Events)**를 활용했습니다.&lt;/p&gt;
&lt;h2 id=&#34;2-스트리밍-시퀀스-다이어그램&#34;&gt;2. 스트리밍 시퀀스 다이어그램&lt;/h2&gt;
&lt;p&gt;서버와 클라이언트 간의 끊임없는 데이터 흐름을 살펴보세요.&lt;/p&gt;
&lt;div class=&#34;mermaid&#34;&gt;
sequenceDiagram
    participant U as User
    participant S as Spring Server (Flux)
    participant A as AI Model (Ollama)
&lt;pre&gt;&lt;code&gt;U-&amp;gt;&amp;gt;S: POST /chat (Request)
Note over S,A: Connection Stay Open
A--&amp;gt;&amp;gt;S: &amp;quot;오늘의&amp;quot; (Token 1)
S--&amp;gt;&amp;gt;U: data: &amp;quot;오늘의&amp;quot;
A--&amp;gt;&amp;gt;S: &amp;quot; 사주는&amp;quot; (Token 2)
S--&amp;gt;&amp;gt;U: data: &amp;quot; 사주는&amp;quot;
Note right of U: 사용자는 실시간으로 글자가 보임
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h2 id=&#34;3-flux와-sse&#34;&gt;3. Flux와 SSE&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;MediaType.TEXT_EVENT_STREAM_VALUE&lt;/code&gt;를 사용하여 AI가 단어(Token)를 생성할 때마다 즉시 클라이언트로 전송합니다. 비차단(Non-blocking) 방식인 WebFlux는 답변을 기다리는 동안 쓰레드를 점유하지 않아 성능적으로도 우수합니다.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<blockquote>
<p><strong>[Dev-Fortune] 시리즈 다시보기</strong></p>
</blockquote>
<ul>
<li><a href="/posts/spring-ai-ollama-chatbot-planning/">1편: 기획부터 스택 선정까지</a></li>
<li><a href="/posts/ollama-spring-boot-local-llm-setup/">2편: 로컬 LLM Ollama 연동</a></li>
<li><a href="/posts/spring-ai-rag-simplevectorstore-ingestion/">3편: RAG와 Vector Store 구축</a></li>
<li><a href="/posts/prompt-engineering-ai-persona-tuning/">4편: 프롬프트 엔지니어링 실전</a></li>
</ul>
<h2 id="1-서론-ai-답변-왜-기다리게-하나요">1. 서론: AI 답변, 왜 기다리게 하나요?</h2>
<p>사용자 경험(UX)을 위해 한 글자씩 타이핑하듯 보여주는 스트리밍 방식은 필수적입니다. 우리 프로젝트는 <strong>WebFlux</strong>와 **SSE(Server-Sent Events)**를 활용했습니다.</p>
<h2 id="2-스트리밍-시퀀스-다이어그램">2. 스트리밍 시퀀스 다이어그램</h2>
<p>서버와 클라이언트 간의 끊임없는 데이터 흐름을 살펴보세요.</p>
<div class="mermaid">
sequenceDiagram
    participant U as User
    participant S as Spring Server (Flux)
    participant A as AI Model (Ollama)
<pre><code>U-&gt;&gt;S: POST /chat (Request)
Note over S,A: Connection Stay Open
A--&gt;&gt;S: &quot;오늘의&quot; (Token 1)
S--&gt;&gt;U: data: &quot;오늘의&quot;
A--&gt;&gt;S: &quot; 사주는&quot; (Token 2)
S--&gt;&gt;U: data: &quot; 사주는&quot;
Note right of U: 사용자는 실시간으로 글자가 보임
</code></pre>
</div>
<h2 id="3-flux와-sse">3. Flux와 SSE</h2>
<p><code>MediaType.TEXT_EVENT_STREAM_VALUE</code>를 사용하여 AI가 단어(Token)를 생성할 때마다 즉시 클라이언트로 전송합니다. 비차단(Non-blocking) 방식인 WebFlux는 답변을 기다리는 동안 쓰레드를 점유하지 않아 성능적으로도 우수합니다.</p>
<h2 id="4-클라이언트에서의-처리">4. 클라이언트에서의 처리</h2>
<p>프론트엔드에서는 <code>fetch</code> API의 <code>getReader()</code>를 사용하여 한 글자씩 화면에 덧붙이는 작업을 수행합니다.</p>
<p><strong>다음 6편에서는 지금까지의 기술들을 하나로 묶어 전체 워크플로우를 심층 분석해 보겠습니다.</strong></p>
]]></content:encoded>
    </item>
  </channel>
</rss>
