MyTetra Share
Делитесь знаниями!
Асинхронный веб, или Что такое веб-сокеты
Время создания: 07.05.2018 22:24
Текстовые метки: websocket web socket
Раздел: WebSocket
Запись: Velonski/mytetra-database/master/base/1525713842innsux7nbd/text.html на raw.githubusercontent.com

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


Как работает HTTP?


Схема обмена сообщениями по HTTP


Вы наверняка знаете, что такое HTTP (или HTTPS), поскольку встречаетесь с этим протоколом каждый день в своём браузере. Браузер постоянно спрашивает у сервера, есть ли для него новые сообщения, и получает их.


Вы также можете знать, что HTTP позволяет использовать разные типы запросов, такие как POST, GET или PUT, каждый из которых имеет своё назначение.


Как работают веб-сокеты?


Схема обмена сообщениями при использовании веб-сокетов


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


Веб-сокеты можно использовать, если вы разрабатываете:


приложения реального времени;

чат-приложения;

IoT-приложения;

многопользовательские игры.

Когда следует избегать использования веб-сокетов?

Практически никогда. Единственный минус — это несовместимость с некоторыми браузерами, но уже 95 % браузеров поддерживают веб-сокеты.


В некоторых случаях веб-сокеты вам всё же не понадобятся. Если вы создаёте простую CMS, вам вряд ли пригодится функциональность в режиме реального времени. Также не стоит использовать веб-сокеты в REST API, поскольку вам хватит таких HTTP-запросов, как GET, POST, DELETE и PUT.


Практические примеры

В примерах ниже для клиента используется JavaScript, а для сервера — Node.js. Примеры очень просты и вряд ли пригодятся на практике, но зато позволят разобраться в сути.


Веб-сокеты

Клиент:


<!DOCTYPE html>

<html>

<head>

<title>Пример чата с веб-сокетом</title>

</head>

<body>

<script>

let ws = new WebSocket("ws://localhost:8080");

// выводим новые сообщения в консоль

ws.onmessage = ({data}) => {

console.log(data);

}

// отправляем сообщение

ws.onopen = () => ws.send('Text');

</script>

</body>

</html>

Сервер:


const WebSocket = require('ws');


// создаём новый websocket-сервер

const wss = new WebSocket.Server({

port: 8080

});


// отправляем клиентам, когда функция clientValidator возвращает true. this — это wss.

wss.broadcast = function(data, clientValidator = () => true) {

this.clients.forEach(client => {

if (clientValidator(client)) {

client.send(data);

}

});

}


wss.on("connection", ws => {

// событие будет вызвано, когда клиент отправит сообщение

ws.on('message', message => {

// отправляем сообщение всем, кроме автора

wss.broadcast(message, client => client !== ws);

});

});

Вот иллюстрация работы веб-сокетов:



Демонстрация работы веб-сокетов


Эквивалент в HTTP

Так как HTTP должен постоянно проверять канал на наличие новых сообщений, можно использовать «грязную» проверку (dirty check) — подход, при котором клиент с заданной периодичностью (допустим, каждые 200 мс) проверяет наличие новых сообщений на сервере.


Чтобы не вникать в XMLHttpRequest, можно использовать библиотеку Axios. Она декларативна и очень понятна.


Клиент:


<!DOCTYPE html>

<html>

<head>

<title>Обмен сообщениями в режиме реального времени</title>

</head>

<body>

<script src="https://unpkg.com/axios/dist/axios.min.js"></script>

<script>

let localMessages = [];


// начальное обновление локального сообщения

axios.get('http://localhost:8080/messages')

.then(({data}) => localMessages = data.messages);


// обновляем список сообщений

const updateMessages = () => {

axios.get('http://localhost:8080/messages')

.then(({data}) => {

const difference = data.messages.splice(localMessages.length);

difference.forEach(message => {

console.log(message);

localMessages.push(message);

});

})

.catch(console.log);

}

// отправляем сообщение

const sendMessage = text => {

axios.post('http://localhost:8080/messages', {text});

}

// каждые 200 мс проверяем, есть ли новые сообщения

setInterval(updateMessages, 200);

</script>

</body>

</html>

Сервер:


const express = require('express');

const bodyParser = require('body-parser');

const app = express();


app.use(bodyParser.json(), function(req, res, next) {

res.header("Access-Control-Allow-Origin", "*");

res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");

next();

});


// в реальном приложении сообщения хранились бы в базе данных или, в некоторых случаях, в JSON-файлах,

// а не в переменной, которая обнуляется при остановке сервера

let messages = [];


// создаем новое сообщение

app.post('/messages', (req, res) => {

messages.push(req.body.text);

res.json({

success: true

});

});


// получаем все сообщения

app.get('/messages', (req, res) => {

res.json({

messages

});

});


// слушаем все запросы на localhost: 8080.

app.listen(8080, () => console.log('Слушаю порт 8080'));

Заключение

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


Перевод статьи «What are Web Sockets?»

Так же в этом разделе:
 
MyTetra Share v.0.65
Яндекс индекс цитирования