Серверная часть Socket.io




На этом уроке

  1. Узнаем, что такое веб-сокеты. Рассмотрим их применение в приложениях реального времени.
  2. Выясним, как использовать эту технологию в Node.js, используя библиотеку Socket.io.
  3. Познакомимся с модулем worker_threads в Node.js.
  4. Научимся выполнять ресурсоёмкие вычисления в отдельных потоках, не блокируя основной.

Оглавление

Теория урока

Введение

Веб-сокеты

Библиотека Socket.io

Серверная часть Socket.io

Клиентская часть Socket.io

Рассылка сообщений

Однопоточность

Модуль worker_threads

Модуль crypto

Заключение

Практическое задание

Глоссарий

Дополнительные материалы

Используемые источники

 

Теория урока

Введение

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

Чтобы мессенджер работал, а клиент получал сообщения от других клиентов, надо научить сервер передавать данные клиенту. Конечно, клиент может сам делать запросы к серверу с определённой частотой, но тогда останется некоторая задержка. А мессенджеры — это приложения реального времени.

Если частота запросов к серверу со стороны клиента будет слишком большой, то возникает вероятность наложения времени выполнения одних запросов на другие. То есть, когда клиент шлёт запрос, сервер его обрабатывает, и пока он его обрабатывает, клиент присылает новый запрос. Это приводит к тому, что до появления ответа от сервера состояние клиента уже поменяется, и данные будут не актуальны.

Однако сам сервер не инициирует соединение с клиентом. У большинства клиентов динамические IP-адреса, и до них нельзя достучаться снаружи.

В результате для реализации такой функциональности используется схема, когда клиент инициирует TCP-соединение с сервером, и оно поддерживается в течение длительного времени в отличие от обычных http-запросов.

Веб-сокеты

Веб-сокет — это стандарт двухсторонней связи клиента с сервером по TCP-соединению, который совместим с HTTP, предназначенный для обмена сообщениями в режиме реального времени.

Чтобы понять отличие веб-сокетов от http-запросов, рассмотрим две схемы применительно к задаче с мессенджером.

В случае с http-запросами схема работы будет примерно такой:

Рис. 1. Получение информации мессенджером посредством http-запросов

На этом рисунке мы видим, что Клиент 1 периодически спрашивает сервер о сообщениях для него. Когда на сервер приходит сообщение от Клиента 2 для Клиента 1 — оно передаётся ему в ответе сервера при следующем опросе. У такого подхода есть несколько недостатков:

  1. Бесполезные запросы. Клиент постоянно опрашивает сервер, то есть нагружает его своими запросами, хотя никакой полезной информации в ответах не передаётся.
  2. С появления на сервере сообщения для клиента и до момента, когда оно передалось клиенту, наблюдается задержка. Чем ниже частота опроса сервера, тем выше задержка.

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

Рис. 2. Получение информации мессенджером посредством веб-сокетов

На рисунке 2 мы видим, что Клиент 1 только один раз устанавливает соединение с сервером. Дальше он просто ждёт, когда ему поступит информация от сервера. Когда на сервер приходит сообщение от Клиента 2, он сразу же отсылает его к Клиенту 1. Это происходит практически моментально, однако на рисунке всё равно изображается некоторая задержка. Её величина зависит от загрузки сервера, его вычислительных возможностей, от скорости соединения с Клиентом 1 и других технических факторов. Однако это совершенно не та задержка, когда сервер ждёт входящего запроса, чтобы передать в ответ данные, как это изображено на рисунке 1.

Таким образом, естественной сферой применения веб-сокетов становятся те приложения, которые работают в режиме реального времени:

  1. Чат-приложения (мессенджеры).
  2. Навигаторы.
  3. Приложения для интернета вещей (IoT-приложения).
  4. Многопользовательские игры.
  5. Прочее.

Сегодня веб-сокеты поддерживаются всеми современными браузерами: Google Chrome, Safari, Mozilla, Opera, Microsoft Edge и т. д.

Библиотека Socket.io

Библиотека Socket.io — это событийно-ориентированная JavaScript-библиотека для веб-приложений и обмена данными в реальном времени.

Она состоит из двух частей:

● клиентской, предназначенной для использования в браузере;

● серверной, предназначенной для использования на стороне сервера Node.js.

В основном Socket.io использует веб-сокеты для своей работы. Однако иногда она применяет и другие технологии — Flash Socket, AJAX Long Polling, AJAX Multipart Stream, не меняя при этом интерфейс. Это удобно. Если пользователь запустит наше приложение на каком-нибудь очень старом браузере, который не поддерживает веб-сокеты, оно всё равно будет работать, используя эти технологии.

Библиотека даёт возможности, которые не может предоставить нативная реализация веб-сокетов, например, одновременную рассылку сообщений нескольким подключённым клиентам.

Эта библиотека используется технологическими гигантами по всему миру для создания приложений реального времени.

В этом уроке мы рассмотрим работу с этой библиотекой с обеих сторон — клиентской и серверной. Создадим базу, показывающую принцип создания чатов, основанного на базе библиотеки Socket.io.

Серверная часть Socket.io

Начнём с серверной части и инициализируем проект:

npm init --yes

 

Официальный сайт говорит, что для установки последней версии пакета, требуется запустить следующую команду:

npm install socket.io

 

В качестве сервера возьмём сервер из предыдущего урока. Для создания же сокетного соединения достаточно дописать несколько строк.

Сначала инициализируем пакет сокета:

const io = require('socket.io');

 

Далее — созданный http-сервер сохраняем в константу:

const app = http.createServer((request, response) => { if (request.method === 'GET') { const filePath = path.join(__dirname, 'index.html'); readStream = fs.createReadStream(filePath); readStream.pipe(response); } else if (request.method === 'POST') { let data = ''; request.on('data', chunk => { data += chunk; }); request.on('end', () => { const parsedData = JSON.parse(data); console.log(parsedData); response.writeHead(200, { 'Content-Type': 'json'}); response.end(data); }); } else { response.statusCode = 405; response.end(); } });

 

Остаётся только проинициализировать точку доступа сокета, описать первые сообщения для подключившихся клиентов и запустить сервер.

const socket = io(app); socket.on('connection', function (socket) { console.log('New connection'); socket.on('CLIENT_MSG', (data) => { socket.emit('SERVER_MSG', { msg: data.msg.split('').reverse().join('')}); }); }); app.listen(3000, 'localhost');

 

Для инициализации точки доступа сокета передадим в модуль io наш созданный http-сервер. Точка доступа сокета может существовать и без этого, однако нам требуется связать её с уже имеющимся http-сервером.

Так как библиотека socket.io событийно-ориентированная, то и работа в библиотеке ведётся по большей части с событиями.

Например, событие ‘connection’ возникает, когда новый клиент подключается к серверу. В нашем случае мы сообщаем об этом соединении в терминал.

Далее создаём обработчик для события 'CLIENT_MSG'. Судя по названию, событие будет ждать сообщения от клиента. В ответ на него сервер станет посылать сообщение, в которое мы записываем принятую строку в обратном порядке.

Последним шагом запускаем http-сервер, чтобы он слушал порт 3000. Так как сервер сокета связан с http-сервером, он также будет слушать порт 3000.



Поделиться:




Поиск по сайту

©2015-2024 poisk-ru.ru
Все права принадлежать их авторам. Данный сайт не претендует на авторства, а предоставляет бесплатное использование.
Дата создания страницы: 2021-12-15 Нарушение авторских прав и Нарушение персональных данных


Поиск по сайту: