Модуль 24

WebSocket та підтримка real-time

Ось готовий урок, створений спеціально за твоїм майстер-промптом.


🎓 CS50: WebSocket та магія Real-time

👋 Привіт, друзі! Я радий бачити вас тут. Сьогодні ми зазирнемо під капот інтернету, щоб зрозуміти, як сайти стають "живими".


1. 🔥 Вступ: Чому ми не можемо просто чекати?

Уявіть, що ви чекаєте на терміновий лист. Що ви робите? Ви йдете до поштової скриньки, відчиняєте її — порожньо. Повертаєтесь додому. Через хвилину знову йдете до скриньки — порожньо. І так кожні 5 хвилин.

Втомлює, правда? Ви витрачаєте сили, зношуєте взуття, а результат — нульовий.

А тепер уявіть, що ви розробляєте месенджер (наприклад, Telegram чи Discord). Якщо ваш додаток працює як та поштова скринька, то, щоб отримати повідомлення від друга, ваш телефон мусить кожну секунду "стукати" на сервер і питати: "Є нові повідомлення? А зараз? А зараз?"

Це називається HTTP Polling, і це жахливо неефективно. * Сервер перевантажений запитаннями. * Ваш трафік "згорає". * Батарея телефону сідає.

Чи не простіше було б провести телефонну лінію? Ви піднімаєте слухавку, ваш друг — теж. Лінія відкрита. Можна мовчати годину, а потім сказати "Привіт!", і друг почує це миттєво. Без ходіння до скриньки.

Ось цю "телефонну лінію" у вебі ми називаємо WebSocket.


2. 🧠 Що там "під капотом"?

Давайте розберемося без складних термінів, але по-суті.

Класичний інтернет працює на HTTP. Це як гра в теніс: 1. Клієнт (ви): Кидаєте м'яч (Request) -> "Дай мені сторінку". 2. Сервер: Відбиває м'яч назад (Response) -> "Тримай сторінку". 3. Кінець гри. Зв'язок розірвано. Щоб отримати щось нове, треба подавати знову.

WebSocket працює інакше. Це тунель. 1. Клієнт каже: "Привіт, сервере! Я хочу перейти з HTTP на WebSocket" (Це називається Handshake або "рукостискання"). 2. Сервер каже: "Окей, давай тримати зв'язок відкритим". 3. Бум! Тепер між вами труба. Дані можуть летіти туди-сюди в будь-який момент, без зайвих церемоній.

📌 Що треба запам'ятати (The Big Picture):

  • Full-duplex: Дані течуть в обидва боки одночасно. Сервер може сам надіслати вам дані, не чекаючи, поки ви попросите!
  • Persistent Connection: З'єднання живе довго (поки хтось не покладе слухавку або не зникне інтернет).
  • Low Latency: Затримка мінімальна. Це ідеально для ігор, бірж та чатів.

Інтуїтивно: HTTP — це рація "Прийом-Відбій". WebSocket — це розмова віч-на-віч.


3. 🧪 Приклади: Від луни до чату

Ми використаємо JavaScript (Node.js), бо це мова вебу, але логіка однакова всюди: хоч у Python, хоч у C++.

Етап 1: Найпростіший сервер (Echo)

Уявіть дзеркало. Ви щось кажете — воно повторює.

Сервер:

const WebSocket = require('ws'); // Беремо бібліотеку
const server = new WebSocket.Server({ port: 8080 });

server.on('connection', socket => {
  console.log('Клієнт під’єднався! 🎉');

  // Слухаємо повідомлення від клієнта
  socket.on('message', message => {
    console.log(`Отримано: ${message}`);
    // Відправляємо назад те саме
    socket.send(`Ти сказав: ${message}`);
  });
});

Що тут відбувається? Ми створили "порт" (двері) 8080. Як тільки хтось заходить, ми вітаємось і на будь-яку фразу відповідаємо тим самим.

Етап 2: Реальний кейс — Біржові котирування 📉

В реальному світі сервер часто сам ініціює спілкування. Наприклад, ціна Біткоїна змінилася.

server.on('connection', socket => {
  console.log('Трейдер на лінії!');

  // Кожну секунду відправляємо нову ціну
  setInterval(() => {
    const price = Math.floor(Math.random() * 1000) + 20000;
    socket.send(JSON.stringify({ asset: 'BTC', price: price }));
  }, 1000);
});

Питання до вас: Якби ми робили це через звичайний HTTP, скільки запитів на сервер нам довелося б відправити за хвилину, щоб бачити ціну щосекунди? (Спойлер: 60! А тут — нуль нових запитів, лише потік даних).


4. 🛠 Практична частина

Прийшов час забруднити руки кодом. У вас є база. Тепер зробіть це самі.

Завдання 1: "Тиша в ефірі" Запустіть код Етапу 1. Підключіться до нього (можна використати онлайн-тестер WebSocket або написати простий клієнтський HTML). Переконайтеся, що "луна" працює.

Завдання 2: "Таймер бомби" 💣 Змініть код сервера так, щоб після підключення він почав зворотний відлік від 10 до 0, відправляючи цифри клієнту. Коли дійде до 0, надішліть "БУМ!" і розірвіть з'єднання (socket.close()).

Завдання 3: "Кімната для обраних" Спробуйте реалізувати логіку: * Якщо клієнт надсилає слово "пароль123", сервер відповідає "Доступ дозволено". * На будь-яке інше повідомлення сервер відповідає "Доступ заборонено" і не підтримує подальшу розмову.

Завдання 4: Міні-кейс "Живий чат" (Advanced) У вас є масив clients = []. Коли хтось підключається — додавайте його в масив. Коли хтось надсилає повідомлення — переберіть масив циклом і відправте це повідомлення всім іншим, крім автора. Це база будь-якого групового чату.


5. 💡 Мислення як у розробника

Як відрізнити новачка від профі, коли мова йде про WebSockets?

1. Помилка "Все через сокет": Новачки настільки радіють, що дані літають миттєво, що починають вантажити через WebSocket все: картинки, великі тексти, HTML сторінок.

Думка профі: "WebSockets — для коротких, швидких подій (лайв-оновлення, сповіщення). Для завантаження профілю користувача я використаю старий добрий HTTP".

2. Проблема зниклого інтернету: WebSocket тримає з'єднання. А що, якщо Wi-Fi клієнта "блимнув"? З'єднання розірветься "тихо".

Думка профі: "Я маю реалізувати механізм Ping/Pong (пульс). Сервер раз на 30 секунд питає 'Ти тут?', а клієнт відповідає 'Тут'. Якщо відповіді немає — я знаю, що клієнт відвалився, і чищу пам'ять".

3. Масштабування: Один сервер може тримати, скажімо, 10 000 з'єднань. А якщо у вас 1 000 000 користувачів? Вам треба 100 серверів. Але як користувач із Сервера 1 відправить повідомлення другу на Сервері 99? Вони ж не знають одне про одного.

Це класична проблема архітектури, про яку ми поговоримо пізніше.


6. 🧩 Підсумок

Отже, що ми маємо в сухому залишку:

  1. HTTP — це повільний лист. WebSocket — це телефонний дзвінок.
  2. WebSocket дозволяє серверу самому стукати до клієнта ("Ей, тут нова ціна!").
  3. Це основа всього Real-time: ігор, чатів, Uber-а, Google Docs.

Тепер ви вмієте: ✅ Розуміти різницю між HTTP та WS. ✅ Створювати простий WebSocket-сервер. ✅ Відправляти та отримувати дані в реальному часі.

🔮 Тизер наступного уроку: Ми навчилися передавати дані миттєво. Але як зробити так, щоб коли ви закрили браузер і відкрили його знову, історія чату збереглася? На наступному уроці ми поговоримо про Бази даних і чому пам'ять сервера — це ненадійне місце для зберігання секретів.

А поки що... це був CS50. До коду! 💻