paint-brush
Как WebSockets обеспечивает работу приложений реального временик@mmenghnani
1,232 чтения
1,232 чтения

Как WebSockets обеспечивает работу приложений реального времени

к Mohit Menghnani7m2025/03/09
Read on Terminal Reader

Слишком долго; Читать

Как WebSockets используются для создания приложений чата в реальном времени!
featured image - Как WebSockets обеспечивает работу приложений реального времени
Mohit Menghnani HackerNoon profile picture

Введение: когда HTTP недостаточно

Берт и Эрни, два друга, работают над сторонним проектом своей мечты: приложением для чата, которое позволяет командам, работающим удаленно, общаться в режиме реального времени. Фронтенд-кодер Берт едва сдерживается, когда делится блестящими новыми функциями со своим другом-специалистом по бэкенду. «Смотри! Я могу набрать сообщение, и оно будет отправлено на сервер, и я вижу, как ответ появляется почти мгновенно!» Эрни, гуру бэкенда, хмурится. «Но как решить проблему, когда два человека пытаются общаться одновременно? Ваше приложение постоянно обновляет страницу вместо того, чтобы позволить вам «видеть» разговор, что делает невозможным общение в режиме реального времени».


Проблема в том, что приложение Берта работает на HTTP, в котором клиент должен запросить выборку с сервера. Эрни резюмирует: «Это как будто все ваши друзья пишут вам в ответ, но затем вы внезапно не видите ни одного ответа, пока не обновите страницу, чтобы проверить, есть ли новые сообщения, потому что они не видят ваше последнее сообщение, пока вы его не обновите, и именно так работает HTTP!»


А вот и самая лучшая часть: для полнофункциональных приложений, работающих в режиме реального времени, есть WebSockets. Эта часть очень захватывающая, поэтому давайте присоединимся к Эрни и Берту и узнаем, как работают WebSockets, каковы процедуры их внедрения, почему они так важны и многое другое.


Что такое WebSockets? Разбор для новичков

WebSockets похожи на непрерывный телефонный звонок между клиентом (вашим веб-браузером) и сервером. Они отличаются от протокола HTTP, который работает по принципу «отправь письмо, жди ответа». С WebSockets обе стороны могут свободно общаться так, как им хочется. Возможности WebSockets включают в себя следующее:


  • Полный дуплекс: клиент и сервер могут передавать данные одновременно.
  • Низкая задержка: нет избыточных повторных рукопожатий; данные могут передаваться свободно.
  • Легковесность: сообщения имеют небольшой размер, что снижает использование полосы пропускания.


Пример: Представьте себе постоянно обновляющееся спортивное табло. С HTTP клиент должен постоянно спамить сервер каждую секунду, «Есть ли изменения в счете?» С WebSockets сервер объявляет «ГОЛ!» в тот момент, когда это происходит.


WebSockets против HTTP: что нового?

Берт откидывается назад и чешет голову. «Но HTTP отлично работает для большинства приложений. Зачем менять правила игры?» Эрни тихо смеется, берет маркер и начинает что-то писать на доске.


«Начнем сверху», — говорит он. «Скажем, обновления в реальном времени, например, результаты спортивных матчей. Клиентам нужно каждую секунду спрашивать сервер: «Есть ли что-то, что мне нужно знать?» Это опрос, поэтому каждые тридцать секунд вам нужно спрашивать: «Мы встречаемся?». Смешно, не так ли? Это также использует большую пропускную способность».


WebSockets меняет ситуацию:

  • Обновления в режиме реального времени: данные на сервер отправляются в момент их изменения; опрос не требуется.
  • Чат-приложения: Не требуется обновления страницы. Сообщения появляются по мере ввода текста.
  • Многопользовательские видеоигры: больше никаких запинающихся движений. Действия отображаются на экранах плавно.


«HTTP довольно хорошо справляется со статическими вещами, такими как блог или страница продукта. Однако, когда дело доходит до живого взаимодействия, требуется постоянное соединение. WebSockets».


Создание приложения для чата в реальном времени: начинается самое интересное

Эрни протирает очки. «Итак, давайте сделаем простое приложение для чата», — восклицает Эрни. «У нас будет сервер Node.js для бэкэнда и приложение React для фронтэнда. Готовы?»

1. Создание бэкэнда Socket.IO

«Возьмите сервер Node.js, потому что он вам понадобится для части Socket.IO», — говорит Эрни, печатая очень быстро:


 npm init -y npm install express socket.io


Код сервера (server.js):

 const express = require('express'); const http = require('http'); const { Server } = require('socket.io'); const app = express(); const server = http.createServer(app); const io = new Server(server); // Serve static files (like React's build folder) app.use(express.static('public')); // Handle WebSocket connections io.on('connection', (socket) => { console.log('New user connected:', socket.id); // Listen for Incoming messages from the socket socket.on('sendMessage', (message) => { console.log('Received:', message); // Broadcast the message to everyone io.emit('receiveMessage', message); }); // Handle user disconnects events socket.on('disconnect', () => { console.log('User left:', socket.id); }); }); server.listen(3000, () => { console.log('Visit http://localhost:3000 on a browser, Server started successful on port 3000'); });


«Клиент и сервер могут общаться друг с другом благодаря обработке соединений WebSocket в Socket.IO. Когда клиент вызывает функцию (sendMessage), сервер отправляет сообщение всем, кто подключен через (io.emit). Довольно просто, не правда ли?»


2. Фронтенд с React

«Теперь моя очередь. Давайте приступим к работе над клиентом React», — говорит Берт.


 npx create-react-app chat-client cd chat-client npm install socket.io-client


Компонент чата (Chat.js):

 import { useState, useEffect } from 'react'; import io from 'socket.io-client'; // Connect to the server const socket = io('http://localhost:3000'); function Chat() { const [message, setMessage] = useState(''); const [messages, setMessages] = useState([]); useEffect(() => { // Listen for new messages socket.on('receiveMessage', (newMessage) => { setMessages([...messages, newMessage]); }); }, [messages]); const sendMessage = () => { if (message.trim()) { socket.emit('sendMessage', message); setMessage(''); } }; return ( <div style={{ padding: '20px' }}> <div> {messages.map((msg, index) => ( <p key={index}>{msg}</p> ))} </div> <input value={message} onChange={(e) => setMessage(e.target.value)} onKeyPress={(e) => e.key === 'Enter' && sendMessage()} /> <button onClick={sendMessage}>Send</button> </div> ); } export default Chat;


Как это работает:

  • Сообщения отправляются сервером через WebSocket всем подключенным клиентам.
  • Приложение React — это одностраничное приложение, способное обновлять пользовательский интерфейс без перезагрузки страницы.

Проверьте это:

  1. Чтобы запустить сервер, введите node server.js в консоли.
  2. Чтобы запустить приложение React, введите npm start в консоли.
  3. Откройте две вкладки в браузере, введите сообщение на одной вкладке и обратите внимание, как почти мгновенно на другой вкладке отобразится то же самое сообщение.

Примеры использования в реальной жизни

Это то, что Берт намеревался построить на основе приложения, но Эрни упоминает: «Большинству реальных приложений требуется некоторая обработка ошибок и способ расширения фреймворка для разработки». Давайте рассмотрим некоторые вероятные проблемы.

1. Линия соединительных остановок

Реализуйте стратегию повторного подключения в клиенте React.

 socket.on('disconnect', () => { console.log('Disconnected. Trying to reconnect...'); socket.connect(); // Auto-reconnect });

2. Идентификация пользователя

Безопасный WebSocket с использованием аутентифицированных токенов JWT.

 // On login, send a token socket.emit('authenticate', { token: 'USER_JWT' }); // Server verifies token socket.on('authenticate', ({ token }) => { if (isValidToken(token)) { socket.authenticated = true; } else { socket.disconnect(); } });

3. Масштабирование с Redis

Внедрить передачу сообщений между различными серверами с использованием Redis.

 npm install redis


Код сервера:

 const redis = require('redis'); const subscriber = redis.createClient(); subscriber.subscribe('chat-channel'); subscriber.on('message', (channel, message) => { io.emit('receiveMessage', message); });

Beyond Chat: Редактирование общего документа

Это следующая идея Берта — редактор, похожий на Google Docs. Эрни говорит: «Вы можете использовать веб-сокеты, чтобы прослушивать изменения, вносимые разными людьми, и объединять их».


Например :

  • Пользователь А печатает: «Привет»

  • Пользователь B удаляет «o» и добавляет «, World»

  • Сервер прослушивает каждое нажатие клавиши и транслирует его всем клиентам, чтобы они могли отобразить ОБНОВЛЕННЫЙ документ.


Фрагмент кода:

 // Client sends keystrokes textarea.addEventListener('input', (e) => { socket.emit('textChange', e.target.value); }); // Server broadcasts changes socket.on('textChange', (text) => { io.emit('updateText', text); });

Проблемы безопасности

Эрни предупреждает нас: «Никогда не используйте WebSockets без HTTPS/WSS!»


  1. Используйте WSS (WebSocket Secure):
 const io = new Server(server, { cors: { origin: "https://yourdomain.com" }, });


  1. Проверяйте все входные данные, чтобы исключить любые данные, которые могут привести к XSS-атакам.


  2. Установить ограничение на количество пользователей, рассылающих спам.


Часто задаваемые вопросы

В: Скорость WebSockets намного выше, чем у HTTP?

A: Да! Для мгновенных приложений WebSockets являются лучшими, поскольку они устраняют необходимость проводить опрос.


В: Возможно ли использовать REST API вместе с WebSockets?

A: Да, определенно! Используйте WebSockets с обновлениями в реальном времени и REST для выполнения операций CRUD.


В: Что делать в случае сбоя сервера?

A: Клиенты могут автоматически переподключаться (см. логику переподключения выше).


Заключительные слова

Чат-приложение Берта теперь пингуется с очарованием в реальном времени, и Эрни улыбается от удовольствия. WebSockets не только для чатов, но и служат целям живых панелей управления, игр, IoT и многого другого.


Ваша очередь: Продолжайте и пробуйте примеры, разрушайте их и создавайте что-то новое. Ваши приложения реального времени ждут!