IlmHamroh
JavaScript Full-stack/29-qism. Backend integratsiyalar: fayl, to'lov, bot, realtime37/69-dars16 daqiqa
Mundarija (31)

Realtime usullari: polling, long polling, SSE yoki WebSocket

Qisqacha: HTTP'da server o'zi gap boshlay olmaydi — faqat so'rovga javob beradi. Yangilikni darhol yetkazishning to'rt yo'li bor: tez-tez so'rash (short polling), javobni yangilik chiqquncha ushlab turish (long polling), bitta ochiq oqim (SSE) va ikki tomonlama kanal (WebSocket). Kanon o'lchovida short polling yangilikni yarim soniyadan ko'proq kechiktirdi, SSE va WebSocket esa bir necha millisekundda yetkazdi. Server faqat xabar beradigan joyda (vazifa o'zgardi, bildirishnoma keldi) SSE yetarli; ikki tomon tinimsiz gaplashsa (chat, o'yin) — WebSocket.

Bu darsda

  • Short polling, long polling, SSE va WebSocket qanday ishlashini bir xil vazifa ustida taqqoslaysiz.
  • Kanonning 100 mijozli o'lchovini o'qiysiz: kechikish (mediana, p95), so'rovlar soni va baytlar.
  • Brauzerning 6 ulanish limitini (HTTP/1.1 da) va uning yechimlarini bilasiz.
  • Vazifaga qarab usul tanlash jadvalini tuzasiz.
  • vazifalar loyihasi uchun nega SSE tanlanganini tushuntirasiz.

Oldin bilishingiz kerak: WebSocket va Server-Sent Events (brauzer tomoni), http.createServer: req va res, HTTP server tomonda: keep-alive, Pub/Sub va Redis Streams.

Oldingi to'lov darslarida server provayderga so'rov yuborardi va webhook kutardi. Endi boshqa savol: server foydalanuvchiga o'zi qanday xabar beradi?

1. Nega bu kerak?

Malika vazifalar ilovasini ikki oynada ochgan: noutbukda va telefonda. Telefonda "Hisobotni topshirish" vazifasini bajarildi deb belgiladi. Noutbukda esa vazifa hali ham ochiq turibdi — sahifani yangilamaguncha.

Sabab — HTTP qanday qurilganida. http.createServer darsida ko'rgansiz: mijoz so'raydi, server javob beradi. Server o'zi birinchi bo'lib "yangilik bor" deya olmaydi. Uning qo'lida faqat kelgan so'rovlar bor.

O'xshatish: pochta bo'limi. Siz posilka kutyapsiz. Birinchi yo'l — har kuni borib "keldimi?" deb so'rash. Ikkinchisi — borib, posilka kelguncha navbatda o'tirish. Uchinchisi — pochtachi uyingizga doim ochiq qo'ng'iroq qilib turadi. To'rtinchisi — pochtachi bilan telefon orqali ikki tomonlama gaplashasiz. Bu to'rt yo'l — darsning to'rt usuli.

Realtime (real vaqt) — yangilik paydo bo'lishi bilan, foydalanuvchi so'ramasdan yetib borishi. "Real vaqt" bu yerda "nol soniya" emas, "odam sezmaydigan darajada tez" degani.

2. Short polling: tez-tez so'rash

2.1 Qanday ishlaydi

Short polling (qisqa so'rash) — mijoz har N soniyada oddiy so'rov yuboradi: "dan=15 dan keyin nima yangi?". Server darhol javob beradi — bo'sh ro'yxat bo'lsa ham.

js
let dan = 0;
setInterval(async () => {
  const javob = await fetch(`/hodisalar?dan=${dan}`);
  for (const h of await javob.json()) {
    korsat(h);
    dan = h.id;
  }
}, 1000);

Kod sodda, serverda hech qanday maxsus narsa yo'q — oddiy REST marshrut. Lekin ikki muammo bor: kechikish va bekor so'rovlar.

2.2 Kechikish: oraliqning yarmi

Hodisa ikki so'rov orasida paydo bo'ladi. Mijoz uni keyingi so'rovda biladi. Oddiy model bilan hisoblaymiz: so'rovlar 0, 1000, 2000 ms da ketadi.

js
// hodisalar paydo bo'lgan vaqt (ms, sahifa ochilgandan beri)
const hodisalar = [120, 450, 980, 1310, 1999, 2500];

// short polling: mijoz har `oraliq` ms da so'raydi
function kechikish(vaqt, oraliq) {
  const keyingiSorov = Math.ceil(vaqt / oraliq) * oraliq;
  return keyingiSorov - vaqt;
}

for (const oraliq of [1000, 5000]) {
  const k = hodisalar.map((t) => kechikish(t, oraliq));
  const ortacha = k.reduce((a, b) => a + b, 0) / k.length;
  const orta = Math.round(ortacha);
  console.log(`${oraliq} ms: ${k.join(" ")} | o'rtacha ${orta}`);
}

Konsolda:

text
1000 ms: 880 550 20 690 1 500 | o'rtacha 440
5000 ms: 4880 4550 4020 3690 3001 2500 | o'rtacha 3774

Kechikish 0 dan butun oraliqgacha tarqaladi, o'rtachasi — taxminan oraliqning yarmi. Oraliqni kamaytirsangiz kechikish kamayadi, lekin so'rovlar ko'payadi.

2.3 So'rovlar narxi

Har so'rov — sarlavhalar, marshrut, ehtimol bazaga murojaat. Javob bo'sh bo'lsa ham.

js
// bir soatda nechta HTTP so'rov ketadi?
function sorovlarSoni(mijozlar, oraliqSoniya, soat = 1) {
  return mijozlar * Math.floor((soat * 3600) / oraliqSoniya);
}

console.log(sorovlarSoni(100, 1));
console.log(sorovlarSoni(10_000, 1));
console.log(sorovlarSoni(10_000, 5));
console.log(sorovlarSoni(10_000, 30));

Konsolda:

text
360000
36000000
7200000
1200000

10 000 ta ochiq oyna, har soniyada so'rov — soatiga 36 million so'rov. Ularning aksariyati "yangilik yo'q" deb qaytadi. Shuning uchun short polling faqat kam foydalanuvchili yoki kam muhim joyda (masalan, admin paneldagi "eksport tayyormi?" tekshiruvi har 5 soniyada) yaxshi.

Tekshirib ko'ring: Short polling oralig'ini 1 soniyadan 30 soniyaga oshirdingiz. Server yuki va kechikish qanday o'zgaradi?

Javob

So'rovlar 30 baravar kamayadi (36 mln → 1.2 mln 10 000 mijozda). O'rtacha kechikish esa ~0.5 s dan ~15 s ga oshadi — oraliqning yarmi. Short polling'da bu ikkisi doim bir-biriga qarshi: birini yaxshilasangiz, ikkinchisi yomonlashadi.

3. Long polling: javobni ushlab turish

Long polling (uzoq so'rash) — mijoz so'raydi, server esa yangilik bo'lmasa javobni darhol bermaydi. U so'rovni ochiq ushlab turadi: yangilik chiqsa — o'sha zahoti javob, chiqmasa — masalan 25 soniyadan keyin bo'sh javob. Mijoz javob olgach darhol keyingi so'rovni yuboradi.

sequenceDiagram
  participant M as Mijoz
  participant S as Server
  M->>S: GET /long?dan=0
  Note over S: yangilik yo'q, kutadi
  S-->>M: 200 [hodisa 1]
  M->>S: GET /long?dan=1
  Note over S: kutadi
  S-->>M: 200 [hodisa 2]
  M->>S: GET /long?dan=2

Diagrammaga qarang: har hodisadan keyin yangi so'rov. Kechikish deyarli yo'q — server yangilikni o'sha zahoti beradi. Lekin hodisa qancha ko'p bo'lsa, so'rov ham shuncha ko'p.

Kanon serveridagi long polling marshruti (formatlangan nusxa):

js
if (u.pathname === "/long") {
  const yangi = hodisalar.filter((h) => h.id > dan);
  if (yangi.length) return yoz(200, JSON.stringify(yangi));
  const k = () => {
    kutuvchilar.delete(k);
    clearTimeout(t);
    yoz(200, JSON.stringify(hodisalar.filter((h) => h.id > dan)));
  };
  const t = setTimeout(k, 25_000);
  kutuvchilar.add(k);
  req.on("close", () => kutuvchilar.delete(k));
  return;
}

Uch nozik joy:

  1. Kutuvchilar ro'yxati. Yangi hodisa chiqqanda server ro'yxatdagi hamma kutuvchini chaqiradi.
  2. Timeout 25 s. Proksi yoki brauzer uzoq jim turgan so'rovni o'zi uzadi (Server timeout'lari va keep-alive). Undan oldin bo'sh javob qaytarish xavfsizroq.
  3. close hodisasi. Mijoz oynani yopsa — kutuvchini o'chiramiz, aks holda ro'yxat to'lib boradi (xotira sizishi).

Long polling hamma joyda ishlaydi: oddiy HTTP, har qanday proksi. Socket.IO WebSocket ishlamagan tarmoqlarda aynan shunga qaytadi (Socket.IO darsida).

4. SSE va WebSocket: bitta ochiq ulanish

4.1 SSE

SSE (Server-Sent Events) — mijoz bitta oddiy GET so'rov yuboradi, server esa javobni tugatmaydi. U text/event-stream turida matn qatorlarini yozib boradi:

text
id: 1
data: {"id":1,"matn":"vazifa yangilandi"}

id: 2
data: {"id":2,"matn":"vazifa yangilandi"}

Brauzerda buni EventSource o'qiydi (WebSocket va Server-Sent Events darsida mijoz tomonini ko'rgansiz). Uzilsa — o'zi qayta ulanadi va oxirgi id ni aytadi. Yo'nalish faqat bitta: server → mijoz. Mijoz serverga gapirmoqchi bo'lsa — oddiy fetch bilan.

4.2 WebSocket

WebSocket — HTTP so'rov bilan boshlanib, keyin boshqa protokolga "ko'chadigan" ulanish. Ko'chgandan keyin ikki tomon ham istalgan paytda xabar yuboradi: matn yoki binar. Bu haqiqiy ikki tomonlama kanal — telefon suhbati kabi.

Narxi: bu endi HTTP emas. Proksi, autentifikatsiya, qayta ulanish, yurak urishi (heartbeat) — hammasini o'zingiz hal qilasiz. WebSocket protokoli va ws darsida buni ochib chiqamiz.

4.3 WebTransport (xabardorlik uchun)

WebTransport — HTTP/3 (QUIC) ustidagi yangi API: bir ulanishda ko'p mustaqil oqimlar va "yetmasa ham bo'ladi" turidagi datagrammalar. O'yinlar va jonli media uchun mo'ljallangan. Kanonda u sinalmagan (TLS va HTTP/3 server kerak). Brauzerlardagi holatini ishlatishdan oldin MDN'dagi moslik jadvalidan tekshiring (2026-10-28).

5. Kanon o'lchovi: 100 mijoz, 20 hodisa

5.1 Tajriba sharti

Kanon bitta Node jarayonida server va 100 mijoz ishga tushirdi. Server 4 soniya davomida har 200 ms da bitta hodisa chiqardi (jami 20). Har hodisa ichida chiqqan vaqt bor — mijoz uni olganda farqni hisobladi. Mashina: i5-12500H, Windows 11, Node 24.21.0; ws 8.22.0, undici 8.12.3 (Node uchun EventSource shu paketdan).

Xom natija. Har qatorda ikki narsaga qarang: kechikish medianasi va HTTP so'rovlar soni:

text
short polling (1 s)        qabul 1900/2000, kechikish mediana 576.2 ms, p95 1005.3 ms, HTTP so'rovlar 400, server chiqargan 94 KB
long polling               qabul 2000/2000, kechikish mediana 34.6 ms, p95 129.1 ms, HTTP so'rovlar 2000, server chiqargan 101 KB
SSE (EventSource)          qabul 2000/2000, kechikish mediana 16.2 ms, p95 29.2 ms, HTTP so'rovlar 0, server chiqargan 127 KB
WS (ws)                    qabul 2000/2000, kechikish mediana 3.8 ms, p95 10.2 ms, HTTP so'rovlar 0, server chiqargan 99 KB
Hodisa mijozga qancha kechikib yetdi (mediana)
  • short polling (1 s)p95 1005.3 ms576,2 ms
  • long pollingp95 129.1 ms34,6 ms
  • SSEp95 29.2 ms16,2 ms
  • WebSocket (ws)p95 10.2 ms3,8 ms

Manba: IlmHamroh kanon o'lchovi, 2026-10-27: Node 24.21.0, ws 8.22.0, undici 8.12.3, 100 mijoz × 20 hodisa, bitta jarayon, lokal, bitta o'lchov

5.2 Mediana va p95

Natijada ikki raqam bor. Nega o'rtacha emas? Bitta sekin javob o'rtachani buzadi:

js
function mediana(sonlar) {
  const s = [...sonlar].sort((a, b) => a - b);
  return s[Math.floor(s.length / 2)];
}

function foizlik(sonlar, p) {
  const s = [...sonlar].sort((a, b) => a - b);
  return s[Math.min(s.length - 1, Math.floor(s.length * p))];
}

const kechikishlar = [4, 5, 5, 6, 6, 7, 8, 9, 15, 240];
console.log("o'rtacha:", kechikishlar.reduce((a, b) => a + b) / 10);
console.log("mediana:", mediana(kechikishlar));
console.log("p95:", foizlik(kechikishlar, 0.95));

Konsolda:

text
o'rtacha: 30.5
mediana: 7
p95: 240

Mediana — saralangan ro'yxatning o'rtasi: "odatdagi" foydalanuvchi shuni his qiladi. p95 (95-foizlik, percentile) — 100 tadan 95 tasi shundan tez: "omadsiz" foydalanuvchi qancha kutadi. O'rtacha 30.5 esa hech kimning tajribasiga mos emas. Kanon ham aynan shu ikki funksiya bilan hisoblagan.

5.3 Natijani o'qiymiz

  • Short polling — mediana 576 ms, p95 bir soniyadan oshdi. Model aytganidek: oraliqning yarmi atrofida. 2000 tadan 1900 tasi yetdi: o'lchov oxirgi hodisadan 600 ms keyin to'xtadi, 1 soniyalik oraliqdagi ba'zi mijozlar oxirgi hodisani so'rashga ulgurmadi. So'rovlar — 400 (100 mijoz × ~4 soniya).
  • Long polling — kechikish keskin kamaydi (35 ms), lekin so'rovlar 2 000 ta: har hodisadan keyin har mijoz qayta so'radi. Har so'rovning sarlavhalari bor.
  • SSE va WebSocket — 0 qo'shimcha so'rov: bitta ulanish butun tajriba davomida ochiq. Kechikish — o'n millisekundlar atrofida.

Halol izoh: bu bitta o'lchov, server va 100 mijoz bitta jarayonda — mijozlarning ishi ham server vaqtini oladi. SSE va WebSocket farqi (16 va 4 ms) shu sharoitda o'lchandi. Biz shunga o'xshash tajribani uch marta qaytardik (Socket.IO darsida) — SSE va WebSocket o'rni almashib turdi. Xulosa: ikkalasi ham odam sezmaydigan darajada tez, farq shovqin ichida. Baytlar ham yaqin: 94–127 KB. SSE'da ko'proq — har xabarga id: va data: prefikslari qo'shiladi.

Tekshirib ko'ring: Long polling kechikishi SSE'ga yaqin. Unda nega long polling bilan qolmaymiz?

Javob

So'rovlar soni: 2000 va 0. Long polling'da har hodisa yangi HTTP so'rov — sarlavhalar, marshrut, auth tekshiruvi, log qatori. Hodisalar tez-tez bo'lsa, server bir xil ishni qayta-qayta qiladi. Bundan tashqari, javob va keyingi so'rov orasidagi qisqa "teshik"da chiqqan hodisa keyingi so'rovgacha kutadi — dan parametri uni yo'qotmaydi, lekin kechiktiradi (p95 129 ms).

6. Brauzerning 6 ulanish limiti

6.1 Kanon tajribasi

HTTP/1.1 da brauzer bitta origin'ga bir vaqtda cheklangan sonda ulanish ochadi. Har SSE ulanishi butun hayoti davomida bittasini band qiladi. Kanon haqiqiy Chromium 151 (Playwright, HTTP/1.1) da bitta sahifadan 7 ta EventSource ochdi va shu paytda oddiy fetch yubordi:

text
ochilgan EventSource: 6/7, fetch 8 ms

6 tasi ochildi, 7-chisi navbatda qoldi. Bu foydalanuvchi ilovani 7 ta tabda ochganda nima bo'lishini ko'rsatadi: 7-tabdagi SSE ishlamaydi.

Kutilmagan qism: oddiy fetch bloklanmadi — 8 ms da javob oldi. Internetda "6 ta SSE ochilsa, sahifadagi hamma so'rovlar to'xtaydi" degan gap ko'p uchraydi. Bu tajribada u kuzatilmadi. Chromium navbatni qanday boshqarishi versiyaga bog'liq bo'lishi mumkin — bitta o'lchovdan umumiy qoida chiqarmaymiz.

6.2 Yechimlar

  1. HTTP/2. Bitta TCP ulanish ichida ko'p mustaqil oqim — limit amalda yo'qoladi. HTTP/2 TLS bilan ishlaydi (HTTPS, TLS va HTTP/2); odatda uni Node oldidagi nginx beradi. Kanonda sinalmagan.
  2. Bitta ulanishni tablar bo'lishadi. Bitta tab SSE'ni ochadi va xabarlarni BroadcastChannel orqali boshqalarga tarqatadi (Oyna va tablar orasida aloqa).
  3. WebSocket bu limitga kirmaydi (brauzer WebSocket ulanishlarini alohida hisoblaydi), lekin uning boshqa narxlari bor.

7. Tanlov

7.1 Taqqoslash jadvali

Savol Short / long polling SSE WebSocket
Yo'nalish mijoz so'raydi server → mijoz ikki tomon
Protokol oddiy HTTP oddiy HTTP Upgrade, keyin boshqa
Qayta ulanish o'zingiz brauzer o'zi, Last-Event-ID o'zingiz
Binar ma'lumot bor yo'q (faqat matn) bor
Savol Short / long polling SSE WebSocket
Auth cookie, sarlavha cookie (sarlavha yo'q) cookie yoki token
Proksi, nginx muammosiz buferlashni o'chirish Upgrade sozlamasi
Server yuki ko'p so'rov ochiq ulanishlar ochiq ulanishlar

7.2 Qaror daraxti

flowchart TD
  A{Mijoz ham tez-tez gapiradimi?} -->|ha: chat, o'yin| W[WebSocket]
  A -->|yo'q| B{Yangilik tez-tez va darhol kerakmi?}
  B -->|yo'q: daqiqada bir| P[Short polling]
  B -->|ha| C{Binar oqim kerakmi?}
  C -->|ha| W
  C -->|yo'q| S[SSE]

Diagrammadan o'qing: birinchi savol — yo'nalish. Bildirishnomalar, vazifa o'zgarishlari, buyurtma holati, AI javobining so'zma-so'z chiqishi — server gapiradi, mijoz tinglaydi. Bularga SSE. "Yozmoqda…" holati bor chat, ko'p o'yinchili o'yin, hamkorlikda tahrir — ikki tomon. Bularga WebSocket.

7.3 Ko'p uchraydigan afsonalar

  • "WebSocket doim tezroq." Kanon o'lchovida farq millisekundlarda va shovqin ichida. Tezlik — tanlov sababi emas.
  • "SSE eskirgan." SSE — HTML standartining bir qismi va hamma zamonaviy brauzerda bor. AI chat xizmatlari javobni aynan SSE formatida oqizadi.
  • "Polling yomon." Kam foydalanuvchi va kam muhim yangilik uchun u eng sodda va ishonchli yo'l. Har narsaning o'z joyi bor.

8. Ko'p uchraydigan xatolar

Xato Nega yomon To'g'risi
har soniyada polling, 10 000 mijoz soatiga 36 mln bekor so'rov SSE yoki oraliqni kattalashtirish
long polling'da close ni tinglamaslik kutuvchilar ro'yxati o'sadi req.on("close") da o'chirish
long polling'da timeout yo'q proksi so'rovni o'zi uzadi 20–30 s da bo'sh javob
bildirishnoma uchun WebSocket auth, proksi, qayta ulanish — hammasi qo'lda SSE
o'rtacha kechikishni o'lchash bitta sekin javob raqamni buzadi mediana va p95
7 tabda SSE, HTTP/1.1 7-tab ulanmaydi HTTP/2 yoki BroadcastChannel

9. Mashqlar

Mashqlar kurs/mashqlar/29/37-realtime/ da.

1-mashq (oson): usulni tanlang

Har vaziyatga usul tanlang (short polling, long polling, SSE, WebSocket) va bir gap bilan sababini yozing:

  1. Admin panelda "Excel eksport tayyormi?" — har 5 soniyada tekshiriladi, 3 ta admin.
  2. Vazifa boshqa oynada o'zgarsa, hamma oynalarda darhol yangilansin.
  3. Ikki kishilik shaxmat o'yini.
  4. AI yordamchi javobini so'zma-so'z chiqarish.
  5. Korporativ tarmoq WebSocket'ni bloklaydi, lekin yangilik darhol kerak.
Yechim
  1. Short polling — foydalanuvchi kam, kechikish muhim emas, server o'zgarmaydi.
  2. SSE — server gapiradi, mijoz tinglaydi; kanon vazifalar uchun aynan shuni tanladi.
  3. WebSocket — ikki tomon ham tez-tez yuboradi (yurishlar).
  4. SSE — bir tomonlama matn oqimi; AI provayderlari ham shu formatda beradi.
  5. Long polling (yoki SSE — u ham oddiy HTTP, lekin ba'zi proksilar oqimni buferlaydi). Long polling har qanday proksidan o'tadi.

2-mashq (o'rta): oraliqni tanlash

engKattaOraliq(maksKechikish) funksiyasini yozing: short polling'da o'rtacha kechikish oraliqning yarmi deb hisoblab, o'rtacha kechikish maksKechikish ms dan oshmaydigan eng katta butun soniyali oraliqni qaytarsin. Keyin 10 000 mijoz uchun soatlik so'rovlarni chiqaring. Uch holat: 500, 3 000 va 20 000 ms. Ishora: Math.floor, darsdagi sorovlarSoni.

Yechim
js
function sorovlarSoni(mijozlar, oraliqSoniya, soat = 1) {
  return mijozlar * Math.floor((soat * 3600) / oraliqSoniya);
}

function engKattaOraliq(maksKechikish) {
  // o'rtacha kechikish ≈ oraliq / 2  →  oraliq ≤ 2 × maks
  return Math.floor((2 * maksKechikish) / 1000);
}

for (const maks of [500, 3000, 20_000]) {
  const s = engKattaOraliq(maks);
  console.log(`${maks} ms → har ${s} s, ${sorovlarSoni(10_000, s)}`);
}

Konsolda:

text
500 ms → har 1 s, 36000000
3000 ms → har 6 s, 6000000
20000 ms → har 40 s, 900000

Talab yarim soniya bo'lsa — soatiga 36 mln so'rov. Shu raqamni ko'rgan jamoa odatda SSE'ga o'tadi. 20 soniyalik talab uchun esa polling bemalol yetadi.

3-mashq (qiyin): long polling simulyatsiyasi

Tarmoqsiz, faqat vaqt raqamlari bilan long polling'ni modellang. Hodisalar [100, 150, 900, 2500] ms da chiqadi. Mijoz 0 ms da so'raydi. Server yangilik bo'lsa darhol, bo'lmasa birinchi yangi hodisada javob beradi va o'sha paytgacha chiqqan hamma yangi hodisalarni beradi. Javob mijozga 10 ms da yetadi, mijoz keyingi so'rovni javob kelgach darhol yuboradi va u ham serverga 10 ms da yetadi. Har hodisaning kechikishini (mijozga yetgan vaqt − chiqqan vaqt) va jami so'rovlar sonini chiqaring.

Yechim
js
const hodisalar = [100, 150, 900, 2500];
const YOL = 10; // ms — so'rov ham, javob ham

let vaqt = 0; // so'rov serverga yetgan payt
let dan = 0; // nechta hodisa olingan
let sorovlar = 0;
const kechikish = [];

while (dan < hodisalar.length) {
  sorovlar++;
  vaqt += YOL; // so'rov serverga yetdi
  // tayyor hodisa bo'lmasa — birinchi yangisini kutamiz
  const javobVaqti = Math.max(vaqt, hodisalar[dan]);
  const yetdi = javobVaqti + YOL;
  while (dan < hodisalar.length && hodisalar[dan] <= javobVaqti) {
    kechikish.push(yetdi - hodisalar[dan]);
    dan++;
  }
  vaqt = yetdi; // mijoz darhol keyingi so'rovni yuboradi
}

console.log("kechikishlar:", kechikish.join(", "));
console.log("so'rovlar:", sorovlar);

Konsolda:

text
kechikishlar: 10, 10, 10, 10
so'rovlar: 4

Hodisalar bir-biridan uzoq bo'lgani uchun har biri 10 ms da yetdi — faqat javob yo'li. Endi [100, 105, 900, 2500] bilan sinab ko'ring: 105 dagi hodisa javob ketayotgan "teshik"ka tushadi va keyingi so'rovgacha kutadi. Kanon o'lchovidagi p95 129 ms aynan shunday teshiklardan.

10. Loyiha qadami: kanon tanlovi

Bu dars loyihaga kod qo'shmaydi — u qaror darsi. Kanon vazifalar uchun yuqoridagi o'lchovdan keyin quyidagini tanladi:

  • Vazifa o'zgarishlari va bildirishnomalar — SSE. Yo'nalish bir tomonlama; oddiy HTTP bo'lgani uchun auth cookie bilan ishlaydi (28-qismda Session-based auth); brauzer o'zi qayta ulanadi va Last-Event-ID bilan o'tkazib yuborilganlarni so'raydi. O'lchovda tezligi WebSocket bilan bir darajada.
  • WebSocket va Socket.IO — taqqoslash tajribasi va ikki tomonlama chat naqshi (Amaliyot: chat va bildirishnomalar). vazifalar-api ga kirmaydi.

Keyingi darsda kanon SseHub modulini yozamiz va uning testlarini ishga tushiramiz.

11. Real ishda

  • AI chatlar (ChatGPT, Claude) javobni SSE formatida oqizadi — API hujjatlarida stream: true shuni beradi.
  • GitHub, Jira kabi xizmatlar bildirishnoma va holat yangilanishlari uchun turli usullarni aralash ishlatadi: muhim joyda ochiq ulanish, qolganida polling.
  • Mobil ilovalar fonda ochiq ulanish ushlay olmaydi — u yerda push bildirishnoma (Push bildirishnomalar).
  • Intervyuda: "Polling, long polling, SSE va WebSocket farqi?", "Bildirishnoma uchun nimani tanlaysiz va nega?", "p95 nima?"

Xulosa

  • HTTP'da server o'zi gap boshlay olmaydi — realtime usullari shu cheklovni aylanib o'tadi.
  • Short polling kechikishi — oraliqning yarmi; so'rovlar mijozlar soniga ko'paytiriladi.
  • Long polling tez, lekin har hodisaga yangi so'rov (kanonda 2 000 ta).
  • SSE va WebSocket — bitta ochiq ulanish; kanonda ikkalasi ham o'n millisekundlar atrofida, farq shovqin ichida.
  • HTTP/1.1 da bitta origin'ga 6 ulanish: 7-SSE ochilmadi; yechim — HTTP/2 yoki tablar bitta ulanishni bo'lishadi.
  • Server gapirsa — SSE, ikki tomon gapirsa — WebSocket.

Keyingi dars: Server-Sent Events — text/event-stream formatini qo'lda yozamiz, Last-Event-ID bilan o'tkazib yuborilganlarni qaytaramiz va kanon SseHub modulini testlari bilan quramiz.

Manbalar

Ulashish:Telegram'da

Izohlar (0)

Izoh yozish uchun kiring.

  • Hozircha izoh yo'q. Birinchi bo'ling!