WebSocket — real-time ulanish

~20 daq · JavaScript · Brauzer API lari

Muammodan boshlaylik

Chat ilovasi yozyapsiz. Ali Vali ga xabar yozdi. Vali o'z sahifasida o'tiribdi — yangi xabar kelganini qanday biladi?

Birinchi fikr: har 2 soniyada serverga so'rov yuborish — "yangi xabar bormi?"

setInterval(async function() {
  const javob = await fetch("/api/xabarlar/yangi");
  const xabarlar = await javob.json();
  if (xabarlar.length > 0) ko_rsat(xabarlar);
}, 2000);

Bu — polling. Ishlaydi. Lekin muammo bor.

Bir soatda 1800 so'rov ketadi — aksariyati "yangi narsa yo'q" javobi. Server behuda yuklanadi. 2 soniyalik kechikish bor — real chat uchun bu sezilarli.

WebSocket — boshqa yondashuv. Serverga bir marta ulanasiz, ulanish ochiq qoladi. Ali xabar yozganida — server o'zi Valiga "xabar keldi" deb yuboradi. So'rov kutish yo'q.


WebSocket nima?

WebSocket — brauzer va server o'rtasidagi doimiy, ikki tomonlama ulanish. Har ikki tomon ham istalgan vaqt xabar yuborishi mumkin — biri so'rov kutib o'tirmaydi.

Hayotiy o'xshatma

HTTP/fetch — xat yozish. Siz xat yozasiz → pochta orqali ketadi → server javob xat yozadi → pochta orqali keladi. Har safar yangi maktub, har safar pochta. Kechikish bor, pochta yuklanadi.

WebSocket — telefon qo'ng'irog'i. Bir marta qo'ng'iroq qilasiz → ikkalangiz ulanasiz → xohlaganingizda gaplasha olasiz → biri qo'yganda ulanish tugaydi. Doimiy kanal, minimal kechikish.


Ulanish yaratish

const ws = new WebSocket("wss://chat.example.com/socket");
//                        ↑
//                    wss:// — xavfsiz WebSocket (HTTPS dagi kabi)
//                    ws://  — xavfsiz bo'lmagan

WebSocket URL da http:// yoki https:// emas — ws:// yoki wss:// ishlatiladi.


To'rtta hodisa — ulanishning hayoti

WebSocket ulanishi to'rt hodisa orqali boshqariladi:

const ws = new WebSocket("wss://chat.example.com/socket");

// 1. Ulanish muvaffaqiyatli ochildi
ws.onopen = function() {
  console.log("Server bilan ulandi!");
  ws.send("Salom, server!"); // ← endi xabar yuborish mumkin
};

// 2. Server xabar yubordi
ws.onmessage = function(event) {
  const malumot = JSON.parse(event.data);
  console.log("Yangi xabar:", malumot);
};

// 3. Xato yuz berdi
ws.onerror = function(xato) {
  console.error("WebSocket xatosi:", xato);
};

// 4. Ulanish yopildi
ws.onclose = function(event) {
  console.log("Ulanish yopildi. Kod:", event.code);
};

Hayotiy o'xshatma — to'rt hodisa

Telefon qo'ng'irog'ini tasavvur qiling:

  • onopen — "Allo, eshitaman" — ulanish o'rnatildi
  • onmessage — narigi taraf gapirdi — xabar keldi
  • onerror — shovqin, ulanish buzildi
  • onclose — "xayr" deb qo'yildi — ulanish tugadi

Xabar yuborish — ws.send()

ws.send() — serverga xabar yuborish. Matn yoki ArrayBuffer yuboriladi. Ob'ekt yuborish uchun JSON.stringify:

ws.onopen = function() {
  // Matn
  ws.send("Salom!");

  // Ob'ekt — JSON.stringify kerak
  ws.send(JSON.stringify({
    tur:     "xabar",
    matn:    "Salom, Vali!",
    vaqt:    Date.now(),
  }));
};

Server ham xuddi shunday yuboradi, brauzer onmessage da qabul qiladi.


Amaliy misol — chat

const ws       = new WebSocket("wss://chat.example.com");
const ro_yxat  = document.getElementById("xabarlar");
const maydon   = document.getElementById("matn-maydon");
const tugma    = document.getElementById("yuborish");

// Serverdan xabar keldi — ro'yxatga qo'shish
ws.onmessage = function(event) {
  const xabar = JSON.parse(event.data);

  const li = document.createElement("li");
  li.textContent = `${xabar.kim}: ${xabar.matn}`;
  ro_yxat.appendChild(li);
};

// Tugma bosildi — serverga yuborish
tugma.addEventListener("click", function() {
  const matn = maydon.value.trim();
  if (!matn || ws.readyState !== WebSocket.OPEN) return;

  ws.send(JSON.stringify({ matn }));
  maydon.value = "";
});

// Ulanish xatosi
ws.onerror = function() {
  console.error("Ulanishda muammo — qayta urinib ko'ring");
};

readyState — ulanish holati

ws.readyState — WebSocket ning hozirgi holati. To'rtta qiymat:

0 — CONNECTING  : ulanish o'rnatilmoqda
1 — OPEN        : ulanish ochiq, yuborish mumkin
2 — CLOSING     : yopilmoqda
3 — CLOSED      : yopildi

Xabar yuborishdan oldin OPEN ekanini tekshirish muhim — CONNECTING holatda send() xato beradi.

if (ws.readyState === WebSocket.OPEN) {
  ws.send("xabar");
} else {
  console.warn("Ulanish hali ochiq emas");
}

Ulanishni yopish

ws.close();        // ← standart yopish (kod 1000 — normal)
ws.close(1000, "Ish tugadi"); // ← sabab bilan yopish

Sahifadan chiqilganda yoki component yo'qolganda — WebSocket yopilishi kerak. Aks holda ulanish "osilgan" holda qoladi.

// Sahifa yopilganda avtomatik yopilish
window.addEventListener("beforeunload", function() {
  ws.close();
});

WebSocket qachon, Fetch qachon?

Bu savol doimo chiqadi. Ikkalasi ham server bilan muloqot uchun — lekin har xil holat uchun.

Fetch — bir martalik so'rov-javob. Foydalanuvchi ma'lumot so'radi → server javob berdi → tugadi. Login, mahsulot olish, forma yuborish.

WebSocket — doimiy ulanish, ikki tomonlama. Server ham istalgan vaqt xabar yuborishi kerak. Chat, o'yinlar, birga tahrirlash (Google Docs), birja narxlari, bildirishnomalar.

Hayotiy o'xshatma

Fetch — do'konga xaridor keldi, xarid qildi, ketdi. Har safar yangi tashrif.

WebSocket — do'kon xodimi ish joyida turadi, mijozlar kelganida xizmat ko'rsatadi. Doim tayyor.


Tez-tez uchraydigan xatolar

OPEN bo'lmasdan send() chaqirish:

const ws = new WebSocket("wss://...");

// ❌ — ws hali CONNECTING holatida, send() xato beradi
ws.send("salom");

// ✅ — onopen da yuborish
ws.onopen = function() {
  ws.send("salom"); // ulanish ochilgandan keyin
};

onmessage da JSON parse xatosini ushlaslik:

// ❌ — server noto'g'ri JSON yuborsa — xato
ws.onmessage = function(event) {
  const data = JSON.parse(event.data);
};

// ✅
ws.onmessage = function(event) {
  try {
    const data = JSON.parse(event.data);
    // ...
  } catch {
    console.warn("Noto'g'ri JSON keldi:", event.data);
  }
};

Ulanishni yopmaslik — xotira oqishi:

WebSocket yopilmasa — server tomonida ham ulanish "osilgan" qoladi. Foydalanuvchi sahifadan chiqsa yoki component o'chsa — ws.close() chaqirilishi kerak.


Xulosa

WebSocket — brauzer va server o'rtasidagi doimiy, ikki tomonlama ulanish. Server ham istalgan vaqt brauzerga xabar yuborishi mumkin.

To'rtta hodisa: onopen (ulandi), onmessage (xabar keldi), onerror (xato), onclose (yopildi).

ws.send(JSON.stringify(data)) — xabar yuborish. ws.close() — sahifadan chiqganda.

Real-time kerak bo'lganda — WebSocket. Bir martalik so'rov-javob uchun — Fetch.


Keyingi dars

52-dars: Intersection Observer — lazy loading uchun