предисловие
С развитием Интернета пользователи предъявляют все более высокие требования к работе в Интернете в режиме реального времени.Например, мониторинг промышленных операций, онлайн-общение в Интернете, системы котировок в реальном времени, онлайн-игры и т. д. и в режиме реального времени передавать изменения, происходящие в фоновом режиме, на сторону браузера, не требуя от пользователя ручного обновления страницы. В этой статье сравниваются и обобщаются прошлые и настоящие популярные технологии web push в реальном времени.
Щелкните полный исходный код этой статьи.Блог на гитхабе, Это мелко на бумаге, я предлагаю вам начать вводить код.
1. Двусторонняя связь
У протокола HTTP есть недостаток: обмен данными может быть инициирован только клиентом. Например, если мы хотим узнать сегодняшнюю погоду, мы можем только сделать запрос от клиента к серверу, и сервер вернет результат запроса. Протокол HTTP не может позволить серверу активно передавать информацию клиенту. Характеристики этого одностороннего запроса обречены быть очень неприятными для клиента, чтобы узнать, есть ли у сервера непрерывные изменения состояния.До появления протокола WebSocket существовало три способа двунаправленной связи: опрос, длительный опрос и потоковая передача iframe..
1. Опрос
- Преимущества: простая реализация, нет необходимости вносить слишком много изменений.
- Недостатки: Если интервал опроса слишком велик, пользователи не смогут вовремя получать обновленные данные, если интервал опроса слишком мал, это приведет к слишком большому количеству запросов и увеличению нагрузки на серверную часть.
// 1.html
<div id="clock"></div>
<script>
let clockDiv = document.getElementById('clock');
setInterval(function(){
let xhr = new XMLHttpRequest;
xhr.open('GET','/clock',true);
xhr.onreadystatechange = function(){
if(xhr.readyState == 4 && xhr.status == 200){
console.log(xhr.responseText);
clockDiv.innerHTML = xhr.responseText;
}
}
xhr.send();
},1000);
</script>
//轮询 服务端
let express = require('express');
let app = express();
app.use(express.static(__dirname));
app.get('/clock',function(req,res){
res.end(new Date().toLocaleString());
});
app.listen(8080);
Запустите локальную службу, откройтеhttp://localhost:8080/1.html, и получены следующие результаты:
2. Долгий опрос (long-polling)
- Преимущества: По сравнению с опросом, он оптимизирован и имеет лучшую своевременность.
- Недостатки: сохранение соединения потребляет ресурсы; сервер не возвращает достоверных данных, время ожидания программы истекло.
// 2.html 服务端代码同上
<div id="clock"></div>
<script>
let clockDiv = document.getElementById('clock')
function send() {
let xhr = new XMLHttpRequest()
xhr.open('GET', '/clock', true)
xhr.timeout = 2000 // 超时时间,单位是毫秒
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
if (xhr.status == 200) {
//如果返回成功了,则显示结果
clockDiv.innerHTML = xhr.responseText
}
send() //不管成功还是失败都会发下一次请求
}
}
xhr.ontimeout = function() {
send()
}
xhr.send()
}
send()
</script>
3. потоковая передача iframe (потоковая передача)
- Преимущества: сообщения могут приходить в режиме реального времени, хорошая совместимость с браузерами.
- Недостатки: сервер поддерживает длительное соединение, что увеличивает накладные расходы; IE, chrome, Firefox будут показывать, что загрузка не завершена, а значок будет продолжать вращаться.
// 3.html
<body>
<div id="clock"></div>
<iframe src="/clock" style="display:none"></iframe>
</body>
//iframe流
let express = require('express')
let app = express()
app.use(express.static(__dirname))
app.get('/clock', function(req, res) {
setInterval(function() {
let date = new Date().toLocaleString()
res.write(`
<script type="text/javascript">
parent.document.getElementById('clock').innerHTML = "${date}";//改变父窗口dom元素
</script>
`)
}, 1000)
})
app.listen(8080)
Запустите локальную службу, откройтеhttp://localhost:8080/3.html, и получены следующие результаты:
В приведенном выше коде клиент запрашивает только один раз, но сервер постоянно отправляет данные клиенту, поэтому сервер поддерживает длительное соединение, что увеличивает накладные расходы.
Выше мы представили три технологии push в реальном времени, но их недостатки очевидны, и они не идеальны для использования.Далее мы сосредоточимся на другой технологии — websocket, которая является идеальной технологией двусторонней связи.
2. Веб-сокет
1. Что такое веб-сокет
WebSocket — это совершенно новый протокол. Благодаря постоянному совершенствованию черновика HTML5 все больше и больше современных браузеров начали полностью поддерживать технологию WebSocket. Он применяет TCP-сокет (сокет) к веб-странице, тем самым обеспечивая связь. Две стороны устанавливают канал связи, который остается активным.
После того как между веб-сервером и клиентом установлено соединение по протоколу WebSocket, все последующие соединения основаны на этом выделенном протоколе. В процессе связи данные в любом формате, таком как JSON, XML, HTML или изображения, могут быть отправлены друг другу.Поскольку это протокол, основанный на HTTP, инициатором соединения по-прежнему является клиент.После установления коммуникационного соединения WebSocket либо сервер, либо клиент могут напрямую отправлять сообщения другой стороне..
Любой, кто новичок в WebSockets, задает один и тот же вопрос: у нас уже есть протокол HTTP, зачем нам еще один протокол?
2. Ограничения HTTP
- HTTP является полудуплексным протоколом, то есть данные могут передаваться одновременно только в одном направлении, клиент отправляет запрос серверу (односторонний), а сервер отвечает на запрос (односторонний).
- Сервер не может активно отправлять данные в браузер. Это затрудняет реализацию некоторых расширенных функций, таких как сценарии чата.
3. Особенности веб-сокета
- Поддержка двусторонней связи, более в режиме реального времени
- Может отправлять текст или двоичные данные
- Уменьшите трафик: пока установлено соединение WebSocket, вы хотите, чтобы оно оставалось подключенным. По сравнению с HTTP сокращаются не только общие накладные расходы на каждое соединение, но и, поскольку информация заголовка WebSocket очень мала, соответственно уменьшается и объем связи.
По сравнению с традиционным режимом HTTP, в котором каждый запрос-ответ требует от клиента установления соединения с сервером, WebSocket представляет собой режим связи, аналогичный длинному TCP-соединению Socket.После установления соединения WebSocket последующие данные передаются в виде последовательность кадров. Прежде чем клиент разорвет соединение WebSocket или сервер разорвет соединение, клиенту и серверу не нужно повторно инициировать запрос на соединение.В случае массового параллелизма и большой нагрузки и трафика взаимодействия клиент-сервер потребление ресурсов пропускной способности сети значительно экономится, и есть очевидные преимущества в производительности, а клиент отправляет и получает сообщения по одному и тому же постоянному соединению.Очевидное сексуальное преимущество.
Далее позвольте мне увидеть, как websocket реализует двустороннюю связь между клиентом и сервером:
// websocket.html
<div id="clock"></div>
<script>
let clockDiv = document.getElementById('clock')
let socket = new WebSocket('ws://localhost:9999')
//当连接成功之后就会执行回调函数
socket.onopen = function() {
console.log('客户端连接成功')
//再向服务 器发送一个消息
socket.send('hello') //客户端发的消息内容 为hello
}
//绑定事件是用加属性的方式
socket.onmessage = function(event) {
clockDiv.innerHTML = event.data
console.log('收到服务器端的响应', event.data)
}
</script>
// websocket.js
let express = require('express')
let app = express()
app.use(express.static(__dirname))
//http服务器
app.listen(3000)
let WebSocketServer = require('ws').Server
//用ws模块启动一个websocket服务器,监听了9999端口
let wsServer = new WebSocketServer({ port: 9999 })
//监听客户端的连接请求 当客户端连接服务器的时候,就会触发connection事件
//socket代表一个客户端,不是所有客户端共享的,而是每个客户端都有一个socket
wsServer.on('connection', function(socket) {
//每一个socket都有一个唯一的ID属性
console.log(socket)
console.log('客户端连接成功')
//监听对方发过来的消息
socket.on('message', function(message) {
console.log('接收到客户端的消息', message)
socket.send('服务器回应:' + message)
})
})
Запустите локальную службу, откройтеhttp://localhost:3000/websocket.html, и получены следующие результаты:
3. Сравнение веб-технологии push-уведомлений в реальном времени
| Способ | тип | Техническая реализация | преимущество | недостаток | Применимая сцена |
|---|---|---|---|---|---|
| Опрос | клиент→сервер | Запрос цикла клиента | 1. Простота реализации. 2. Поддержка междоменного доступа. | 1. Пустая трата пропускной способности и ресурсов сервера 2. Большая часть информации запроса бесполезна (полная информация заголовка HTTP) 3. Задержка 4. Большая часть недействительных запросов | Подходит для небольших приложений |
| Долгий опрос | клиент→сервер | Сервер удерживает соединение и возвращается до тех пор, пока не появятся данные или тайм-аут, что уменьшает количество повторных запросов. | 1. Простая реализация 2. Отсутствие частых запросов 3. Экономия трафика 4. Низкая задержка | 1. Сервер удерживает соединение, которое потребляет ресурсы 2. Большая часть запрошенной информации бесполезна | WebQQ, Привет веб-версия, Facebook IM |
| длинное соединение iframe | клиент→сервер | Вставьте скрытый iframe в страницу, установите атрибут src этого iframe в запрос на длительное соединение, и сервер сможет непрерывно вводить данные клиенту. | 1. Доставка данных в режиме реального времени 2. Никаких бесполезных запросов, одна ссылка, несколько "пушей" | 1. Сервер увеличивает накладные расходы 2. Невозможно точно узнать статус подключения 3. IE, хром и т.д. всегда будут в состоянии загрузки | Чат Gmail |
| WebSocket | сервер⇌клиент | new WebSocket() | 1. Поддержка двусторонней связи, более высокая производительность в режиме реального времени. 2. Можно отправлять двоичные файлы. 3. Уменьшить количество сообщений. | 1. Степень поддержки браузера непостоянна 2. Отключение и повторное подключение не поддерживаются | Онлайн-игры, банковские операции и платежи |
Подводя итог: протокол Websocket не только решает пассивность сервера в протоколе HTTP, то есть связь может быть инициирована только клиентом, но и решает проблему задержки синхронизации данных, а также приносит очевидные преимущества в производительности, поэтому websocket Это идеальное решение для веб-технологии push-уведомлений в реальном времени, но если вы хотите быть совместимым с браузерами с более низкими версиями, вы можете рассмотреть возможность опроса.
Порекомендуйте полезный инструмент мониторинга ошибок для всехFundebug, добро пожаловать, чтобы попробовать это бесплатно!
Добро пожаловать в публичный аккаунт:Мастер по фронтенду, мы будем свидетелями вашего роста вместе! Если вы чувствуете, что что-то приобрели, пожалуйста, дайте мне вознаграждение, чтобы мотивировать меня выпускать больше высококачественного контента с открытым исходным кодом.
Справочная статья
- Учебник по веб-сокетам
- Курс по интерфейсной архитектуре Everest
- Краткий обзор технологии веб-передачи в реальном времени
- WebSocket (1): эволюция «проталкивания в реальном времени» на стороне сервера
- Сравнение основных серверных технологий push-уведомлений, таких как длинное соединение/веб-сокет/SSE.