Server-Sent Events (SSE) در HTML
درس قبل، Web Workers جاوااسکریپت را در thread پسزمینه اجرا میکرد و با postMessage با صفحه حرف میزد — کار CPU محلی، بدون استریم سرور. این درس محاسبهٔ خارج از thread را ترک میکند و Server-Sent Events (SSE) را معرفی میکند: سرور جریان بهروزرسانی متنی را روی HTTP به مرورگر هل میکند. HTML هنوز اسکریپت بار میکند؛ اسکریپت EventSource باز میکند، به message گوش میدهد و وقتی e.data آمد DOM را میکشد. دامنه عملی است — باز کردن، گوش دادن، هل یکطرفه — نه سرور استریم Node یا کورس کامل realtime.
چرا SSE در کورس HTML
مبتدی برای امتیاز زنده، لاگ یا وضعیت بدون پروتکل سوکت سفارشی به ابزار نیاز دارد. SSE اولین API رایج برای «سرور متن را روی HTTP هل میکند» است. بعد از «صفحه و worker محلی پیام میدهند»، تقسیم اینجا فرق دارد: سرور مالک استریم است؛ اسکریپت صفحه مالک EventSource و DOM. new EventSource(url)، onmessage / onerror، و ایدهٔ text/event-stream کافی است.
پاسخ مستقیم
۱) const es = new EventSource("/events") بسازید (با URL واقعی وقتی بکاند دارید). ۲) es.onmessage را مدیریت کنید و e.data را بخوانید. ۳) وقتی رویداد آمد DOM را روی صفحه بهروز کنید. ۴) برای قطع/تلاش مجدد es.onerror را در نظر بگیرید. ۵) SSE یکطرفه است: سرور → مرورگر. ۶) برای پیام دوطرفه مداوم WebSockets؛ برای بهروزرسانی نادر polling؛ برای CPU محلی Workers.
📊 SSE vs WebSocket vs Worker
| Topic | SSE (this lesson) | WebSocket | Web Worker (prev) |
|---|---|---|---|
| Typical role | Server→browser text stream | Full duplex messages | Local off-thread compute |
| Browser entry | EventSource(url) | new WebSocket(url) | new Worker(url or Blob) |
| Direction | One-way (server push) | Two-way | Page ↔ worker (no server required) |
| Transport idea | HTTP text/event-stream | WS protocol | postMessage / onmessage |
| DOM updates | On the page script | On the page script | On the page script only |
| This course depth | Required (browser pattern) | Contrast only | Previous lesson |
| Not this lesson | Full backend stream servers | Chat product design | SharedWorker fleets |
الگوی کوچک گوشدادن EventSource
این قطعه فقط سمت مرورگر را نشان میدهد. /events باید endpoint واقعی SSE باشد؛ بدون سرور اتصال خطا میدهد — باز هم شکل API را آموزش میدهد.
<pre id="out">Waiting for stream…</pre>
<script>
const out = document.getElementById("out");
const es = new EventSource("/events");
es.onmessage = function (e) {
out.textContent = "Last update: " + e.data;
};
es.onerror = function () {
out.textContent = "SSE error or closed (need a real /events stream)";
};
</script>
خواندن فراخوانیهای listen
new EventSource("/events")استریم HTTP بلندمدت باز میکندonmessageوقتی سرور رویداد پیشفرضmessageمیفرستد اجرا میشودe.dataبار متنی آن رویداد است- صفحه در
<pre>مینویسد — همان مالکیت DOM مثل Workers، منبع داده متفاوت - برخلاف Web Workers از
postMessageبه thread پسزمینه خبری نیست — هل سرور است - بدون سرور سازگار،
onerrorدر دموی محلی انتظار میرود - مقدمه را کوچک نگه دارید: یک URL، یک handler، یک نوشتن DOM
افزودن خطوط استریم به لاگ
UIهای زنده اغلب هر رویداد را اضافه میکنند نه جایگزین یک خط. این دمو چند خط آخر را در لیست نگه میدارد.
<ul id="log"></ul>
<script>
const log = document.getElementById("log");
const es = new EventSource("/events");
es.onmessage = function (e) {
const li = document.createElement("li");
li.textContent = e.data;
log.appendChild(li);
while (log.children.length > 5) {
log.removeChild(log.firstChild);
}
};
es.onerror = function () {
if (!log.dataset.noted) {
log.dataset.noted = "1";
const li = document.createElement("li");
li.textContent = "Stream not available — wire a text/event-stream URL";
log.appendChild(li);
}
};
</script>
خواندن ایدهٔ لاگ
- هر
onmessageیک<li>ازe.dataمیسازد - لیست را محدود کنید تا دمو خوانا بماند
- هنوز یکطرفه: صفحه از EventSource به سرور
postMessageنمیفرستد - هنوز Web Worker نیست — بدون Blob worker یا حلقهٔ جمع
- رویدادهای نامدار در API هست؛
messageپیشفرض برای مقدمه کافی است - وقتی دیگر لازم نیست
es.close()بزنید - درس بعدی اختیاری: XHTML تاریخچه و مارکآپ چندگانه
انتخاب SSE، polling، سوکت یا worker
- هل مکرر وضعیت/لاگ از سرور روی HTTP: مناسب مقدمهٔ SSE
- تازهسازی نادر هر چند دقیقه: polling ساده ممکن است کافی باشد
- چت دوطرفه مداوم: WebSockets را در نظر بگیرید
- حلقهٔ محلی سنگین که اسکرول را قفل میکند: آن Web Workers بود
- کشیدن کارت به منطقهٔ خطچین: آن Drag and Drop بود
- ساختن خود endpoint استریم Node/Django: فراتر از مقدمهٔ مرورگر HTML
تمرین — باز کنید، گوش دهید، مقایسه کنید
- قطعهٔ listen EventSource را بخوانید؛
onmessageوonerrorرا ببینید. - شکل پاسخ
text/event-streamرا در مستندات معتبر مرور کنید. - قطعهٔ append-log را بخوانید؛ بگویید چرا صفحه DOM را بهروز میکند نه سرور.
- جمله: Web Workers محلی خارج از thread محاسبه میکنند؛ SSE رویداد هلشده از سرور میگیرد.
- جمله: SSE یکطرفه است؛ WebSockets جایگزین رایج دوبلکس کامل است.
- (اختیاری) وقتی بکاند دارید EventSource را به URL واقعی SSE وصل کنید.
- جلوتر: XHTML مارکآپ XML-مانند — نه استریم زنده.
اشتباهات آسان
- انتظار ارسال مرورگر→سرور از EventSource مثل WebSocket
- اشتباه گرفتن SSE با Web Workers (استریم سرور ≠ thread CPU پسزمینه)
- فراموش اینکه سرور باید قالب/نوع محتوای event-stream سازگار بفرستد
- استفاده از SSE برای بهروزرسانیهایی که یک fetch کافی است
- نادیده گرفتن
onerrorتا شکست خاموش شبیه صفحهٔ خراب شود - گرفتن این مقدمه بهعنوان کورس کامل استریم بکاند یا محصول WebSocket
- قاطی کردن سازندههای
EventSourceباWorkerیاWebSocket
خلاصه
- SSE بهروزرسانی متنی سرور→مرورگر را روی HTTP استریم میکند
- از
EventSourceاستفاده کنید؛onmessage/onerror؛ DOM را روی صفحه بکشید - هل یکطرفه؛ برای دوبلکس کامل WebSockets
- Web Workers محاسبهٔ محلی خارج از thread بود؛ این درس هل سرور است
- دموی واقعی به URL با
text/event-streamنیاز دارد؛ الگوی مرورگر بهتنهایی مهم است - بعدی: XHTML برای تاریخچهٔ سند XML-مانند در کورس
🧠 دانش خود را بیازمایید
دانش خود را بیازمایید
خود را با این آزمون تعاملی به چالش بکشید و ببینید موضوع را چقدر خوب درک کردهاید
📝 دستورالعملها
- هر سوال را با دقت بخوانید
- بهترین پاسخ را برای هر سوال انتخاب کنید
- میتوانید آزمون را هر چند بار که میخواهید تکرار کنید
- پیشرفت شما در بالا نمایش داده میشود