SSE (Server Sent Event)

TCP ์ฐ๊ฒฐ ์๋ฆฝ
โ HTTP GET /sse
โ HTTP 200 OK (ํค๋)
โ SSE ์ด๋ฒคํธ ๋ฐ์ดํฐ ๋ฐ๋ณต ์ ์ก
โ ํด๋ผ์ด์ธํธ๊ฐ ์ฐ๊ฒฐ ์ข
๋ฃ
โ ์๋ฒ ACK
โ ์์ธ์ RST ๋ฐ์Phase 1: TCP 3-Way Handshake
TCP 3-Way Handshake ๊ณผ์ ์ WebSocket ๋ถ์ ์์ ๋์ผํ๋ฏ๋ก ์๋ตํฉ๋๋ค.
332~334๋ฒ ํจํท์์ ESTABLISHED ์ํ๊ฐ ๋์์ต๋๋ค.
Phase 2: SSE Handshake (HTTP Request & Response)
WebSocket์ 101 Switching Protocols๋ก ์
๊ทธ๋ ์ด๋ ํ์ง๋ง SSE๋ ํ์ค HTTP ์์ฒญ์ ์ ์งํ๋ ์๋ต์ ์ข
๋ฃํ์ง ์๊ณ ์ด์ด๋๋ ๋ฐฉ์์
๋๋ค.
SSE๋ ํ๋กํ ์ฝ ์ ๊ทธ๋ ์ด๋๊ฐ ์๋,
HTTP ์ฐ๊ฒฐ์ ์ฅ๊ธฐ ์ ์ง(Long-lived HTTP Connection)
[Packet-335]: Client โ Server (HTTP GET /sse)
ํด๋ผ์ด์ธํธ๊ฐ Server-Sent Events(SSE) ๊ตฌ๋ ์ ์์ํ๊ธฐ ์ํ HTTP ์์ฒญ์ ์ ์กํฉ๋๋ค.
์ด ํจํท์ TCP ์ฐ๊ฒฐ์ด ์ด๋ฏธ ESTABLISHED ์ํ์ธ ์ํฉ์์ ์ ์ก๋๋ฉฐ, SSE ํต์ ์ ์์์ ์ ํด๋นํฉ๋๋ค.

ํด๋ผ์ด์ธํธ๋ GET /sse HTTP/1.1 ์์ฒญ์ ํตํด ์๋ฒ์ ์ด๋ฒคํธ ์คํธ๋ฆผ์ ์์ฒญํฉ๋๋ค.
Accept: text/event-streamโ ํค๋๋ฅผ ํตํด ์๋ต ๋ฐ์ดํฐ๊ฐ ์ผ๋ฐ์ ์ธ HTTP ๋ฆฌ์์ค๊ฐ ์๋, ์ด๋ฒคํธ ์คํธ๋ฆผ ํ์์์ ๋ช ์ํฉ๋๋ค.Connection: keep-aliveโ ํค๋๋ ์๋ฒ๊ฐ ์๋ต์ ์ฆ์ ์ข ๋ฃํ์ง ์๊ณ , ํ๋์ HTTP ์๋ต์ ์ฅ์๊ฐ ์ ์งํ๋ฉฐ ๋ฐ์ดํฐ๋ฅผ ์ง์์ ์ผ๋ก ์ ์กํ ๊ฒ์ ์๋ฏธํฉ๋๋ค.
SSE๋ WebSocket๊ณผ ๋ฌ๋ฆฌ ํ๋กํ ์ฝ ์ ๊ทธ๋ ์ด๋(Upgrade) ๊ณผ์ ์ด ์กด์ฌํ์ง ์์ผ๋ฉฐ, ์ด ๋จ์ผ HTTP ์์ฒญ ์ดํ ๋ณ๋์ ์ ํ๋ฆฌ์ผ์ด์ ๊ณ์ธต ํธ๋์ ฐ์ดํฌ๋ ์ํ๋์ง ์์ต๋๋ค.
์ด ์์ฒญ์ ๋ฐ์ดํฐ Payload๋ฅผ ํฌํจํ์ง ์๋ ๋จ๋ฐ์ฑ ์์ฒญ์ด๋ฉฐ, ์ดํ์ ๋ชจ๋ ๋ฐ์ดํฐ ์ ์ก์ ์๋ฒ๊ฐ ๋ณด๋ด๋ HTTP ์๋ต ์คํธ๋ฆผ์ ํตํด ์ด๋ฃจ์ด์ง๋๋ค.
๋ฐ๋ผ์ ์ด ํจํท์ WebSocket์์์ Upgrade Request์ ๋์๋๋ ์ญํ ์ ์ํํ์ง๋ง, ํ๋กํ ์ฝ ์ ์ด ์์ด HTTP ์ฐ๊ฒฐ์ ์ ์งํ๋ค๋ ์ ์์ ๊ทผ๋ณธ์ ์ธ ์ฐจ์ด๋ฅผ ๊ฐ์ง๋๋ค.
TCP ๊ณ์ธต์์๋ PSH, ACK ํ๋๊ทธ๊ฐ ์ค์ ๋ ์ผ๋ฐ ๋ฐ์ดํฐ ์ธ๊ทธ๋จผํธ๋ก ์ ์ก๋๋ฉฐ, TCP๋ ์ดํ ์ ์ก๋ SSE ์ด๋ฒคํธ์ ๊ฒฝ๊ณ๋ ์๋ฏธ๋ฅผ ์ธ์งํ์ง ๋ชปํ๊ณ ๋จ์ํ ๋ฐ์ดํธ ์คํธ๋ฆผ์ผ๋ก๋ง ์ฒ๋ฆฌํฉ๋๋ค.
[Packet-336]: Server โ Client (ACK)
ํด๋ผ์ด์ธํธ๊ฐ ๋ณด๋ธ [Packet-335] (GET /sse) ์์ฒญ์ "์ ๋ฐ์์ต๋๋ค."๊ณ ์๋ฒ์ OS(TCP ๊ณ์ธต)๊ฐ ์๋ตํ๋ ๊ฒ์
๋๋ค. (TCP ๊ณ์ธต์ ์์ ํ์ธ ํจํท)
์ด ACK์ ์ ํ๋ฆฌ์ผ์ด์ (Spring, Node.js ๋ฑ)์ด ์๋ต์ ๋ง๋ค๊ธฐ๋ ์ ์, OS ๋ ๋ฒจ์์ ๋ณด๋ด๋ ์์ ํ์ธ ํจํท์ ๋๋ค.
[Packet-337, 339]: Server โ Client (PSH, ACK)
์๋ฒ๊ฐ ์์ฑํ HTTP 200 OK ์๋ต ํค๋(Response Header) ๋ฐ์ดํฐ์ ์ค์ ์ ์ก ๊ตฌ๊ฐ์
๋๋ค.
์๋ฒ๊ฐ ๋ณด๋ผ HTTP ์๋ต ํค๋์ ์์ด ๊ฝค ๋๊ธฐ ๋๋ฌธ์, TCP ๊ณ์ธต์์ ์ด๋ฅผ ๋ ๊ฐ์ ์กฐ๊ฐ(Segment)์ผ๋ก ๋๋์ด ์ ์กํฉ๋๋ค.
์ด ํจํท๋ค์๋ PSH(PUSH) ํ๋๊ทธ๊ฐ ์ค์ ๋์ด ์๋๋ฐ, ์ด๋ ์์ ์ธก์์ ๋ฐ์ดํฐ๋ฅผ ๋ฒํผ์ ์ง์ฐ์ํค์ง ์๊ณ ,
์ฆ์ ์์ ๊ณ์ธต(์ ํ๋ฆฌ์ผ์ด์ )์ผ๋ก ์ ๋ฌํ๋๋ก ์ ๋ํ๊ธฐ ์ํ ํํธ์ ๋๋ค.
์์ด์ด์คํฌ์ Info ์ปฌ๋ผ์ ํ์๋ [TCP PDU reassembled in 341]๋ ๋ค์์ ์๋ฏธํฉ๋๋ค.
337๋ฒ, 339๋ฒ ํจํท์ ๋ฌผ๋ฆฌ์ ์ผ๋ก ๋ถํ ๋ TCP ์ธ๊ทธ๋จผํธ (์ ์ก ๋จ์๋ก ํด์ ๊ฐ๋ฅ)
์ด ๋์ ์ฌ์กฐ๋ฆฝํ๋ฉด, 341๋ฒ์์ ํ์ธ ๊ฐ๋ฅํ ์์ ํ HTTP ์๋ต ๋ฉ์์ง๊ฐ ๋จ
์ฆ, "์ด ํจํท(337, 339)๋ค์ ์กฐ๊ฐ๋ ๋ฐ์ดํฐ์ด๋, 341๋ฒ์์ ์กฐ๋ฆฝ๋ ์์ฑ๋ณธ์ ๋ณด์ฌ์ฃผ๊ฒ ๋ค"๋ ๋ป์ ๋๋ค.
[Packet-338, 340]: Client โ Server (ACK)
์ด ๊ณผ์ ์ HTTP๋ SSE์๋ ๋ฌด๊ดํ์ง๋ง, ํด๋ผ์ด์ธํธ๋ ์๋ฒ๋ก๋ถํฐ TCP ์ธ๊ทธ๋จผํธ๋ฅผ ํ๋ ์์ ํ ๋๋ง๋ค, ๊ฐ ์ธ๊ทธ๋จผํธ์ ๋ํด ์์ฐจ์ ์ผ๋ก ์์ ํ์ธ(ACK)์ ๋ฐํํฉ๋๋ค.
Packet-338 โ Packet-337 ์์ ์๋ฃ ํ์ธ
Packet-340 โ Packet-339 ์์ ์๋ฃ ํ์ธ
์ฝ๊ฒ ์๊ธฐํ๋ฉด, ์๋ฒ๊ฐ ๋ณด๋ธ ์กฐ๊ฐ(337๋ฒ, 339๋ฒ)์ ํ๋ ๋ฐ์ ๋๋ง๋ค ํด๋ผ์ด์ธํธ๊ฐ "1๋ฒ ์กฐ๊ฐ ๋ฐ์(338)", "2๋ฒ ์กฐ๊ฐ ๋ฐ์(340)" ํ๊ณ ํ์ธํ๋ ๊ณผ์ ์ ๋๋ค.
[Packet-341]: Server โ Client (HTTP/1.1 200 OK)
์๋ฒ๊ฐ ํด๋ผ์ด์ธํธ์ GET /sse ์์ฒญ์ ๋ํ HTTP ์๋ต ํค๋๋ฅผ ๋ชจ๋ ์ ์กํ ๊ฒฐ๊ณผ์
๋๋ค.
์ด ํญ๋ชฉ์ ์ค์ ๋ก ์๋ก์ด ํจํท์ด ์ ์ก๋ ๊ฒ์ด ์๋๋ผ, ์์ ์๋ฒ๊ฐ ๋ณด๋ธ TCP ์ธ๊ทธ๋จผํธ๋ค([Packet-337], [Packet-339])์ ๋ด๊ธด ๋ฐ์ดํธ๋ฅผ ์์ด์ด์คํฌ๊ฐ ํ๋์ HTTP ์๋ต์ผ๋ก ํฉ์ณ์ ๋ณด์ฌ์ฃผ๋ ํ์์
๋๋ค.
์ฆ, ์์ด์ด์คํฌ๊ฐ ๋ ผ๋ฆฌ์ ์ผ๋ก ์ฌ์กฐ๋ฆฝ(Reassembled)ํ์ฌ ๋ณด์ฌ์ฃผ๋
๊ฐ์์ ๊ฒฐ๊ณผ๊ฐ์ ๋๋ค.
์ด ์์ ๋ถํฐ ํด๋ผ์ด์ธํธ๋ ํด๋น ์ฐ๊ฒฐ์ SSE ์ด๋ฒคํธ ์คํธ๋ฆผ์ผ๋ก ํด์ํ๊ธฐ ์์ํฉ๋๋ค.
์๋ต์๋ ๋ค์๊ณผ ๊ฐ์ ์ ๋ณด๊ฐ ํฌํจ๋์ด ์์ต๋๋ค.
์ํ ์ฝ๋:
HTTP/1.1 200 OKContent-Type: text/event-streamโ ์๋ต์ Body๋ ์ด๋ฒคํธ ์คํธ๋ฆผ์์ ์๋ฏธConnection: keep-aliveโ ์ฐ๊ฒฐ์ ์ข ๋ฃํ์ง ์๊ณ ์ ์งํจ
์ด ์๋ต์ด ์ ๋ฌ๋๋ฉด์, ์๋ฒ๋ ๋ค์์ ๋ช ํํ ํฉ๋๋ค.
์ด ์ฐ๊ฒฐ์ ์์ฒญโ์๋ต์ผ๋ก ๋๋ด์ง ์์ต๋๋ค.
ํ๋์ HTTP ์๋ต์ ์ ์งํ ์ฑ, ์๋ฒ๊ฐ ํ์ํ ๋๋ง๋ค ์ด๋ฒคํธ ๋ฐ์ดํฐ๋ฅผ ๊ณ์ ์ ์กํฉ๋๋ค.
๋ฐ๋ผ์ ์ด ์์ ์ดํ,
ํด๋ผ์ด์ธํธ๋ ๋ ์ด์ ์๋ฒ ์๋ต์ โ๊ธฐ๋ค๋ฆฌ๋ ์ํโ๊ฐ ์๋๋ผ, ์ด๋ฆฐ HTTP ์๋ต ์คํธ๋ฆผ์ ์์ ํ๋ ์ํ๊ฐ ๋ฉ๋๋ค.
์ฆ, ์๋ฒ๊ฐ ๋ณด๋ด๋ ๋ชจ๋ SSE ์ด๋ฒคํธ๋ ์ด HTTP ์๋ต์ ๋ณธ๋ฌธ(Body)์ ์ฐ์์ ์ผ๋ก ์ถ๊ฐ๋๋ฉฐ, TCP ๊ณ์ธต์์๋ ์ด๋ฅผ ๋จ์ํ ๋ฐ์ดํธ ์คํธ๋ฆผ์ผ๋ก๋ง ์ฒ๋ฆฌํฉ๋๋ค.
[Packet-342]: Client โ Server (ACK)
ํด๋ผ์ด์ธํธ๊ฐ ์๋ฒ์์ ์ ์กํ HTTP ์๋ต ๋ฐ์ดํฐ(337, 339 โ ๋ ผ๋ฆฌ์ ์ผ๋ก 341)๋ฅผ ์ ์์ ์ผ๋ก ์์ ํ์์ TCP ๊ณ์ธต์์ ํ์ธ(ACK)ํ๋ ํจํท์ ๋๋ค.
์ด ํจํท์ ์ ํ๋ฆฌ์ผ์ด์ ๊ณ์ธต(HTTP/SSE)๊ณผ๋ ์ง์ ์ ์ธ ์๋ฏธ๊ฐ ์์ผ๋ฉฐ, TCP์ ์ ๋ขฐ์ฑ ๋ณด์ฅ ๋ฉ์ปค๋์ฆ์ ์ํด ์๋์ผ๋ก ์ ์ก๋๋ ์์ ํ์ธ ํจํท์ ๋๋ค.
๋ฌผ๋ฆฌ์ ์๋ฏธ:
๋ฐฉ๊ธ ์ Packet-341์ ์์ด์ด์คํฌ์์ โHTTP ์๋ต ์์ฑ๋ณธ'์ผ๋ก ํํ๋์์ง๋ง, ์ค์ ๋ฌผ๋ฆฌ์ ๋คํธ์ํฌ์์์๋ ๋ง์ง๋ง ๋ฐ์ดํฐ(7 bytes)๋ฅผ ๋ด์ ํจํท์ด์์ต๋๋ค.
ACK ๋ฒํธ ๊ณ์ฐ: ์ด์ ๊น์ง ํ์ธํ ๋ฒํธ(287) + ๋ฐฉ๊ธ ๋ฐ์ ๋ฐ์ดํฐ ํฌ๊ธฐ(7) = ACK(294)
๋ ผ๋ฆฌ์ ์๋ฏธ (Handshake Completed):
์ด ํจํท์ ๋์ผ๋ก SSE ์ฐ๊ฒฐ ์๋ฆฝ์ ์ํ ์ด๊ธฐ ๋ฐ์ดํฐ ๊ตํ์ด ๋ง๋ฌด๋ฆฌ๋์๋ค๋ ๊ฒ์ ์๋ฏธํฉ๋๋ค.
์ด ์์ ๋ถํฐ ํด๋ผ์ด์ธํธ๋ Passive Receiver๋ก ์ ํ๋๋ฉฐ, ์๋ฒ๊ฐ ์ด๋ฒคํธ๋ฅผ PUSH ํด์ค ๋๋ง๋ค ACK๋ง ๋ณด๋ด๋ ์ญํ ์ ์ํํฉ๋๋ค.
[Follow TCP Stream]
์ด ๊ธฐ๋ฅ์ TCP ์ฐ๊ฒฐ์์ ์ค๊ฐ ๋ชจ๋ ๋ฐ์ดํธ๋ฅผ ์๊ฐ ์์๋๋ก ๋ณด์ฌ์ค๋๋ค.
SSE๋ ์์ฒญ 1๋ฒ + ์๋ต 1๋ฒ + ์ฐ๊ฒฐ ์ ์ง + Body์ ๋ฐ์ดํฐ๋ฅผ ๊ณ์ ์ถ๊ฐํ๋ ๊ตฌ์กฐ์ด๊ธฐ ๋๋ฌธ์,
GET /sse ์์ฒญ
HTTP/1.1 200 OK ์๋ต ํค๋
๊ทธ ๋ค์ ์ด์ด์ง๋ ๋ชจ๋ ์ด๋ฒคํธ ๋ฐ์ดํฐ
์ด ๋ชจ๋ ๊ฒ์ด ํ๋์ TCP ์คํธ๋ฆผ ์์ ๋ค์ด์์ด์ 341๋ฒ ํจํท์ ๊ธฐ์ค์ผ๋ก Follow ํ๋ฉด ์ ์ฒด ๋ํ ๋ด์ฉ์ด ๋ณด์ ๋๋ค.

์ด๋ฏธ์ง๋ฅผ ๋ณด๋ฉด, ๋๋์ง ์๋ HTTP ์๋ต์ Body์, ์๋ฒ๊ฐ chunk ๋จ์๋ก ์ด๋ฒคํธ๋ฅผ ๊ณ์ ์จ ๋ด๋ ค๊ฐ๋ ๊ตฌ์กฐ์ธ ๊ฒ์ ํ์ธํ ์ ์์ต๋๋ค.
Phase 3: Data Transmission (Event Stream)
HTTP ์๋ต ํค๋๊ฐ ๋ชจ๋ ์ ๋ฌ๋๊ณ (SSE ํธ๋์
ฐ์ดํฌ ์๋ฃ), ํด๋ผ์ด์ธํธ๊ฐ ์ด๋ฅผ text/event-stream์ผ๋ก ํด์ํ๊ธฐ ์์ํ ์ดํ์ ๋จ๊ณ์
๋๋ค.
์ฆ, HTTP/1.1 200 OK ์๋ต ํค๋๊ฐ ๋๋๊ณ Body ์ ์ก์ด ์์๋ ์ดํ์ ๋จ๊ณ์ ๋๋ค.
์ด Phase์์๋ ์๋ก์ด HTTP ์์ฒญ์ด๋ ์๋ต์ด ์ค๊ฐ์ง ์์ต๋๋ค. ์ด๋ฏธ ์ด๋ ค ์๋ ๋จ ํ๋์ HTTP/1.1 200 OK ์๋ต์ Body์ ์๋ฒ๊ฐ ์๊ฐ ๊ฐ๊ฒฉ์ ๋๊ณ ๋ฐ์ดํฐ๋ฅผ ๊ณ์ ์ถ๊ฐ(Append)ํฉ๋๋ค.
์ ์ฒด ํจํท์ ๋ํ๋ธ ์ด๋ฏธ์ง๋ ์๋ฒ๊ฐ ์ฝ 5์ด ๊ฐ๊ฒฉ์ผ๋ก ์ด 3๋ฒ์ ์ด๋ฒคํธ๋ฅผ ํด๋ผ์ด์ธํธ์๊ฒ PUSH ํ๋ ๊ณผ์ ์ ๋๋ค.
๊ฐ ์ฌ์ดํด์ [์๋ฒ์ ๋ฐ์ดํฐ ์ ์ก(PSH)] โ [ํด๋ผ์ด์ธํธ์ ์์ ํ์ธ(ACK)] ํจํด์ด ๋์ผํ๊ฒ ๋ฐ๋ณต๋ฉ๋๋ค.
Follow TCP Stream ์น์
์ ์ด๋ฏธ์ง๋ฅผ ๋ณด๋ฉด, id=0๊น์ง SSE ์ฐ๊ฒฐ ์๋ฆฝ์ ํ์ํ ๋ฐ์ดํฐ๋ฅผ ๋ํ๋ด๊ณ ,
id=1 ๋ถํฐ 890~2899๋ฒ ํจํท์์ ์ค๊ฐ ๋ฐ์ดํฐ๊ฐ ํ์๋ฉ๋๋ค. (Packet Bytes์์ ํ์ธ ๊ฐ๋ฅ)
[Packet-890 ~ 894]: Server โ Client (์ฒซ ๋ฒ์งธ ์ด๋ฒคํธ ์ ์ก)
์ด๋ฒคํธ:
id:1๋ฉ์์ง ๋ฐ์๋์:
SSE ์ฐ๊ฒฐ์ด ๋งบ์ด์ง๊ณ ์ฝ 5์ด(ํธ๋์ ฐ์ดํฌ ์๊ฐ ํฌํจ) ๋ค, ์๋ฒ๊ฐ ์ฒซ ๋ฒ์งธ ๋ฐ์ดํฐ๋ฅผ ๋ณด๋ ๋๋ค.
๋ฐ์ดํฐ๊ฐ TCP ์ธ๊ทธ๋จผํธ ์ฌ๋ฌ ๊ฐ(890, 892 ๋ฑ)๋ก ๋ถํ ๋์ด ์ ์ก
Wireshark๋ ์ด๋ฅผ Packet-894์์ ํ๋์ HTTP PDU๋ก ์ฌ์กฐ๋ฆฝํ์ฌ ํ์
๋ด์ฉ:
Follow TCP Stream์์ ํ์ธํ ์ฒซ ๋ฒ์งธ JSON ๋ฐ์ดํฐ๊ฐ ์ด ํจํท๋ค์ ๋ด๊ฒจ ์์ต๋๋ค.์๋ก์ด HTTP ์๋ต์ด ์๋๋ผ, ๊ธฐ์กด 200 OK ์๋ต Body์ ์ผ๋ถ์ ๋๋ค.
[Packet-895]: Client โ Server (ACK)
ํด๋ผ์ด์ธํธ๊ฐ ์๋ฒ๋ก๋ถํฐ ์ฒซ ๋ฒ์งธ ์ด๋ฒคํธ ๋ฐ์ดํฐ(890~894๋ฒ ๋ด์ฉ)๋ฅผ ๋ชจ๋ ์ ๋ฐ์์์ ์๋ฏธํ๋ ํจํท์ ๋๋ค.
ํด๋ผ์ด์ธํธ๊ฐ ์๋ฒ๋ก๋ถํฐ ์์ ํ ๋ฐ์ดํฐ ๋ฐ์ดํธ ๋ฒ์์ ๋ํด ๋ค์์ ๊ธฐ๋ํ๋ ์ํ์ค ๋ฒํธ๋ฅผ ACK๋ก ์๋ตํ ํจํท์ ๋๋ค.
Len=0โ Payload ์์
[Packet-900]: Client โ Server (FIN, ACK)
ํด๋ผ์ด์ธํธ์ ์ฐ๊ฒฐ ์ข ๋ฃ ์์ฌ (Active Close)
์ํฉ:
์ฌ์ฉ์๊ฐ ๋ธ๋ผ์ฐ์ ํญ์ ๋ซ์๊ฑฐ๋, ํ์ด์ง๋ฅผ ์ด๋ํ์ฌ ํด๋ผ์ด์ธํธ๊ฐ "์ด์ ์ฐ๊ฒฐ ๋์๊ฒ์."๋ผ๊ณ ์ ์ธํ์ต๋๋ค.
FIN ํ๋๊ทธ:
"ํด๋ผ์ด์ธํธ๋ ๋ ์ด์ ์๋ฒํํ ๋ณด๋ผ ์์ฒญ(๋ฐ์ดํฐ)์ด ์์ด์. ํด๋ผ์ด์ธํธ์ ๋งํ๊ธฐ(Write) ๊ธฐ๋ฅ์ ๋๊ฒ์."
์ด ์์ ์์ ํด๋ผ์ด์ธํธ๋
FIN_WAIT_1์ํ๊ฐ ๋ฉ๋๋ค.FIN์ ์ฐ๊ฒฐ ์ ์ฒด ์ข ๋ฃ๊ฐ ์๋๋ผ, ์ก์ ๋ฐฉํฅ(write side) ์ข ๋ฃ๋ฅผ ์๋ฏธํฉ๋๋ค.
[Packet-901]: Server โ Client (ACK)
์๋ฒ๋ ํด๋ผ์ด์ธํธ์ FIN ํจํท ์์ ํ์ธ
์ํฉ:
์๋ฒ์ OS(TCP ๊ณ์ธต)๊ฐ ํด๋ผ์ด์ธํธ์ FIN ํจํท์ ์์ ํ๊ณ , ํ์ธํ๋ค๋ ์๋ต ํฌํจ
์ํ ๋ณํ:
์๋ฒ๋
CLOSE_WAIT์ํ๊ฐ ๋ฉ๋๋ค.์ค์: OS๋ ์์์ง๋ง, ์๋ฒ ์ ํ๋ฆฌ์ผ์ด์ (Spring ๋ฑ)์ด ์์ง ์์ผ์ ์ ๋ซ์, ์๋ต ์คํธ๋ฆผ๋ ์ ์ง ์ค
ํด๋ผ์ด์ธํธ๋
FIN_WAIT_2์ํ๊ฐ ๋ฉ๋๋ค.
[Packet-1676 ~ 1680]: Server โ Client (๋ ๋ฒ์งธ ์ด๋ฒคํธ ์ ์ก)
์ด๋ฒคํธ:
id:2๋ฉ์์ง ๋ฐ์๋์:
์ฒซ ๋ฒ์จฐ ์ด๋ฒคํธ ์ ์ก๊ณผ ์์ ํ ๋์ผํ TCP ์ ์ก ๊ณผ์ (PSH, ACK)์ ๊ฑฐ์นฉ๋๋ค.
1676๋ฒ(ํค๋ ๋ถ๋ถ) + 1678๋ฒ(๋ฐ๋ ๋ถ๋ถ)์ผ๋ก ๋๋์ด ์ ์ก๋ ํ, 1680๋ฒ์์ ํ๋๋ก ์กฐ๋ฆฝ(Reassembled)๋์ด ๋ณด์ ๋๋ค.
Point:
ํด๋ผ์ด์ธํธ๊ฐ
FIN์ ๋ณด๋์์๋ ์๋ฒ๋ ์ฌ์ ํ ๋ฐ์ดํฐ๋ฅผ ์ ์กํ๊ณ ์์ต๋๋ค.์๋ฒ๋ ์์ง
CLOSE_WAIT์ํ์๋ต ์คํธ๋ฆผ์ ๋ซ์ง ์์๊ธฐ ๋๋ฌธ์ ์ฐ๊ธฐ(write)๊ฐ ๊ฐ๋ฅํฉ๋๋ค.
[Packet-1681]: Client โ Server (ACK)
์์์ ํด๋ผ์ด์ธํธ๋ ์ด๋ฏธ Packet-900์์ FIN์ ๋ณด๋๋๋ฐ, ์ ์ดํ์ ์๋ฒ๊ฐ ๋ณด๋ธ ๋ฐ์ดํฐ์ ๋ํด ๋ค์ ACK(ํ์ฌ ํจํท, 1681)๋ฅผ ๋ณด๋ผ๊น์?
์์ธ์ TCP Half-Close ๋์ ๊ท์น์ ์์ต๋๋ค.
TCP์์ FIN์ ์ฐ๊ฒฐ ์ ์ฒด ์ข
๋ฃ๊ฐ ์๋๋ผ ์ก์ ๋ฐฉํฅ ์ข
๋ฃ๋ฅผ ์๋ฏธํฉ๋๋ค.
์ฆ, Client FIN (Packet-900)๋ ๋ ์ด์ ์๋ฒ๋ก ๋ณด๋ผ ๋ฐ์ดํฐ๊ฐ ์๋ค๋ ๊ฒ์ ์๋ฏธํฉ๋๋ค.
์๋ฒ๋ก๋ถํฐ ๋ ์ด์ ๋ฐ์ดํฐ๋ฅผ ๋ฐ์ง ์๊ฒ ๋ค๋ ์๋ฏธ๊ฐ ์๋๋๋ค.
ํด๋ผ์ด์ธํธ OS๋
FIN_WAIT_2์ํ๋ก, ๋ค์ด์ค๋ ๋ฐ์ดํฐ์๋ ACK ์๋ต์ ์ ์กํฉ๋๋ค.
์๋ฒ๋ ์์ง ์์ผ์ ๋ซ์ง ์์๊ณ ํด๋ผ์ด์ธํธ ์ญ์ ์์ ๊ฒฝ๋ก๋ ์ด๋ฆฐ ์ํ์ ๋๋ค.
[Packet-2879 ~ 2899]: Server โ Client (์ธ ๋ฒ์งธ ์ด๋ฒคํธ ์ ์ก)
์ด๋ฒคํธ:
id:3๋ฉ์์ง ๋ฐ์๋์:
๋ง์ง๋ง์ผ๋ก
count:3๋ฐ์ดํฐ๋ฅผ ์ ์กํฉ๋๋ค.
[PSH(PUSH) ํ๋๊ทธ์ ์๋ฏธ]
์ด ๊ตฌ๊ฐ์ ์๋ฒ ํจํท ๋ค์์๋ PSH ํ๋๊ทธ๊ฐ ์ค์ ๋์ด ์์ต๋๋ค.
์ด๋ TCP ์คํ์์ ๋ค์๊ณผ ๊ฐ์ ์๋ฏธ๋ฅผ ๊ฐ์ง๋๋ค.
โ์ด ๋ฐ์ดํฐ๋ ๋ฒํผ์ ์์๋์ง ๋ง๊ณ โ,
์ฆ์ ์ ํ๋ฆฌ์ผ์ด์ ๊ณ์ธต(๋ธ๋ผ์ฐ์ )์ผ๋ก ์ ๋ฌํ๋ผ๋ ์ ํธ์ ๋๋ค.
SSE๋ ์ค์๊ฐ ์ ๋ฌ์ด ํต์ฌ์ด๊ธฐ ๋๋ฌธ์, ์ด Phase์์ PSH๊ฐ ์์ฃผ ๋ฑ์ฅํ๋ ๊ฒ์ ์ ์์ ์ด๊ณ ์๋๋ ๋์์ ๋๋ค.
Phase 4: Exceptional Termination (RST)
ํด๋ผ์ด์ธํธ๊ฐ ์ก์ ์ข ๋ฃ(FIN)๋ฅผ ํ์์๋ ์๋ฒ๊ฐ ๋ฐ์ดํฐ๋ฅผ ๊ณ์ ๋ณด๋ผ ๋ ๋ฐ์ํ ์ ์๋ ๋ง์ง๋ง ๋จ๊ณ์ ๋๋ค.
[Packet-2900]: Client โ Server (RST)
์ํฉ:
์๋ฒ๊ฐ ์ธ ๋ฒ์งธ ๋ฐ์ดํฐ(id:3)๋ฅผ ์ ์กํ์ ๋ ํด๋ผ์ด์ธํธ๊ฐ ๋ณด๋ด๋ ํจํท์ ๋๋ค.
RST(Reset) ํ๋๊ทธ:
"๋๋ ์ด ์ฐ๊ฒฐ์ ๋ํด ๋ ์ด์ ์ฒ๋ฆฌํ ์ ์์ผ๋, ์ฆ์ ์ฐ๊ฒฐ์ ๊ฐ์ ์ข ๋ฃ(Abort)ํ๊ฒ ๋ค"๋ ๊ฐ๋ ฅํ ์ ํธ์ ๋๋ค.
๋ฐ์ ์์ธ:
์ ํ๋ฆฌ์ผ์ด์ ๊ณ์ธต์ ๋ถ์ฌ: ํด๋ผ์ด์ธํธ ๋ธ๋ผ์ฐ์ ๊ฐ ์ด๋ฏธ ํญ์ ๋ซ์๊ฑฐ๋ ํ์ด์ง๋ฅผ ์์ ํ ๋ ๋์ ์์ ๋ฒํผ์ ์๋ ๋ฐ์ดํฐ๋ฅผ ์ฒ๋ฆฌํ ํ๋ก์ธ์ค๊ฐ ์ฌ๋ผ์ง ๊ฒฝ์ฐ์ ๋๋ค.
๋ถ์ ์ ํ ๋ฐ์ดํฐ ์์ : TCP ๊ณ์ธต์ ์ด์์์ด ACK๋ฅผ ๋ณด๋๋๋ผ๋(1681๋ฒ), ์ ํ๋ฆฌ์ผ์ด์ ์ด ์ด๋ฏธ ์์ผ์ ๋ซ์๋ฒ๋ฆฐ ์ํ์์ ๋ฐ์ดํฐ๊ฐ ๊ณ์ ๋ค์ด์ค๋ฉด OS๋ RST๋ฅผ ๋ณด๋ด ์ฐ๊ฒฐ์ ํ๊ดดํฉ๋๋ค.
๊ฒฐ๋ก :
SSE๋ ์๋ฒ๊ฐ ์ฐ๊ฒฐ์ ์ฃผ๋๊ถ์ ๊ฐ์ง๋ง, ํด๋ผ์ด์ธํธ๊ฐ ์ข ๋ฃ๋ฅผ ์ํ ๋ ์๋ฒ๊ฐ ์ด๋ฅผ ๊ฐ์งํ์ง ๋ชปํ๊ณ ๊ณ์ ๋ฐ์ดํฐ๋ฅผ ํธ์ํ๋ฉด ์ด์ฒ๋ผ RST์ ํจ๊ป ์ฐ๊ฒฐ์ด ๋น์ ์์ ์ผ๋ก ๋๋ ์ ์์ต๋๋ค.
๋ฐ๋ผ์ ์๋ฒ ์ธก์์๋ ํด๋ผ์ด์ธํธ์ ์์ฒญ ์ข ๋ฃ๋ฅผ ์ ์ ํ ํธ๋ค๋ง(Exception Handling)ํ์ฌ ์์์ ํด์ ํ๋ ๊ฒ์ด ์ค์ํฉ๋๋ค.
Summary
1. ์ฐ๊ฒฐ ์๋ฆฝ (Handshake)
ํ์ค HTTP ํ์ฉ:
WebSocket๊ณผ ๋ฌ๋ฆฌ 101 Switching Protocols ๊ณผ์ ์์ด, ์ผ๋ฐ์ ์ธ GET ์์ฒญ์ ์ฅ๊ธฐ ์ ์ง(Long-lived)ํ๋ ๋ฐฉ์์ ๋๋ค.
๊ธฐ์กด HTTP 1.1 ์ด์์ ์ธํ๋ผ๋ฅผ ๊ทธ๋๋ก ์ฌ์ฉํฉ๋๋ค. ์ด๋ ๋ฐฉํ๋ฒฝ์ด๋ ํ๋ก์ ์๋ฒ ํ๊ฒฝ์์๋ ๋ณ๋ ์ค์ ์์ด ์ค์๊ฐ ํต์ ์ด ๊ฐ๋ฅํ๋ค๋ ๊ฐ๋ ฅํ ์ฅ์ ์ด ๋ฉ๋๋ค.
ํ์ ํด๋ผ์ด์ธํธ ํค๋:
Accept: text/event-stream: ์๋ฒ์๊ฒ ์ด๋ฒคํธ ์คํธ๋ฆผ ํ์์ ์๋ต์ ์๊ตฌํฉ๋๋ค.Cache-Control: no-cache: ๋ธ๋ผ์ฐ์ ๊ฐ ์ด์ ์ด๋ฒคํธ๋ฅผ ์บ์ฑํ์ง ์๊ณ ์ค์๊ฐ์ผ๋ก ๋ฐ๋๋ก ๋ณด์ฅํฉ๋๋ค.Connection: keep-alive: TCP ์ฐ๊ฒฐ์ ๋์ง ์๊ณ ๊ณ์ ์ ์งํฉ๋๋ค.
2. ๋ฐ์ดํฐ ์ ์ก ๋ฐฉ์
๋จ๋ฐฉํฅ(Unidirectional): ์๋ฒ์์ ํด๋ผ์ด์ธํธ๋ก๋ง ๋ฐ์ดํฐ๋ฅผ ๋ณด๋ ๋๋ค. ํด๋ผ์ด์ธํธ์์ ์๋ฒ๋ก ๋ฐ์ดํฐ๋ฅผ ๋ณด๋ผ ๋๋ ๋ณ๋์ HTTP ์์ฒญ์ ์ฌ์ฉํด์ผ ํฉ๋๋ค.
์ค์๊ฐ์ฑ ๋ณด์ฅ (PSH Flag): TCP ๊ณ์ธต์์
PSHํ๋๊ทธ๋ฅผ ์ ๊ทน์ ์ผ๋ก ์ฌ์ฉํ์ฌ, ๋ฒํผ๋ง ์์ด ์ฆ์ ์์ ์ ํ๋ฆฌ์ผ์ด์ ์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌํฉ๋๋ค.์๋ ์ฌ์ฐ๊ฒฐ(Auto Reconnect): ๋ธ๋ผ์ฐ์ ์
EventSourceAPI๋ ์ฐ๊ฒฐ์ด ๋๊ธฐ๋ฉด ์๋์ผ๋ก ์ฌ์ฐ๊ฒฐ์ ์๋ํ๋ฉฐ, ์๋ฒ๊ฐid๊ฐ์ ํจ๊ป ๋ณด๋ด์ฃผ๋ฉด ๋ง์ง๋ง ๋ฐ์ ์ง์ ๋ถํฐ ๋ณต๊ตฌ๊ฐ ๊ฐ๋ฅํฉ๋๋ค.
3. ์ฐ๊ฒฐ ์ข
๋ฃ ๋ฐ ์์ ๊ด๋ฆฌ
Half-Close์ ํจ์ : ํด๋ผ์ด์ธํธ๊ฐ ํญ์ ๋ซ์
FIN์ ๋ณด๋ด๋๋ผ๋, ์๋ฒ๋ ์ด๋ฅผ ๊ฐ์งํ๊ธฐ ์ ๊น์ง ๋ฐ์ดํฐ๋ฅผ ๊ณ์ ๋ณด๋ผ ์ ์์ต๋๋ค.RST ํจํท์ ๊ฒฝ๊ณ : ํด๋ผ์ด์ธํธ ์ ํ๋ฆฌ์ผ์ด์ ์ด ์ด๋ฏธ ์ข ๋ฃ๋ ์ํ์์ ์๋ฒ๊ฐ ๋ฐ์ดํฐ๋ฅผ ํธ์ํ๋ฉด
RSTํจํท์ด ๋ฐ์ํ๋ฉฐ ๊ฐ์ ์ข ๋ฃ๋ฉ๋๋ค.์๋ฒ ์ธก ๋์: ์๋ฒ๋ ํด๋ผ์ด์ธํธ์ ์ฐ๊ฒฐ ์ํ๋ฅผ ์ฃผ๊ธฐ์ ์ผ๋ก ํ์ธํ๊ฑฐ๋, ๋ฐ์ดํฐ ์ก์ ์ ๋ฐ์ํ๋ ์์ธ(Broken Pipe ๋ฑ)๋ฅผ ์บ์นํ์ฌ ์ฌ์ฉํ์ง ์๋ ์ฐ๊ฒฐ์ ์ฆ์ ์ ๋ฆฌํด์ผ ์๋ฒ ์์ ๋์๋ฅผ ๋ง์ ์ ์์ต๋๋ค.
์ฌ์ฉ์ค์ธ ์ค๋ ๋ ๋ฑ
Last updated