درس ۲۳ از ۳۳

Streamable HTTP در عمق (StreamableHTTP in depth)

عنوان اصلی: StreamableHTTP in depth

هدف یادگیری: handle کردن SSE چندجریانی، resumability، و cursor به نام Last-Event-ID.

مفاهیم کلیدی: per-stream SSE event ID، header Last-Event-ID، semantic redelivery، چند stream هم‌زمان، cancellation با CancelledNotification.

وقتی یک request یک SSE stream باز می‌کند، هر eventای که server emit می‌کند می‌تواند یک id داشته باشد که در سطح session/stream globally unique است. اگر اتصال drop شود، client می‌تواند با ارسال یک GET با Last-Event-ID: <last-id> reconnect کند و server می‌تواند eventهایی که قرار بود بعد از آن بیایند را replay کند. مهم: replay per-stream است — server نباید پیام‌های یک stream دیگر را روی streamای که reconnect می‌کند replay کند.

یک client می‌تواند چند SSE stream را هم‌زمان باز نگه دارد (مثلاً یکی به ازای هر request طولانی). Server باید هر پیام را روی دقیقاً یک stream بفرستد — هرگز broadcast نکند.

قطع شبکه cancellation نیست. برای cancel، client باید یک CancelledNotification صریح روی یک POST تازه بفرستد.

مثال عملی — wire (resume بعد از قطع اتصال)

GET /mcp HTTP/1.1
Host: example.com
Accept: text/event-stream
Mcp-Session-Id: 1868a90c-7e8d-4c3b-a1f2-...
Last-Event-ID: evt-00042
MCP-Protocol-Version: 2025-06-18

اشتباهات رایج

  • replay بین streamها. spec ممنوع کرده.
  • رفتار با eventهای progress مثل response. progress یک notification است؛ response جداگانه می‌آید.
  • reconnect بدون Last-Event-ID و تعجب از اینکه پیام‌ها گم می‌شوند.