Мало знаний, большой вызов! Эта статья участвует в "Необходимые знания для программистов«Творческая деятельность.
Введение
Наступая на хвост конца года, планируя на следующий год и закладывая хороший фундамент для работы в следующем году, я начал процесс собеседования, поскольку в проекте используется WebSocket, интервьюер неизбежно упомянет WebSocket при глубоком копании опыта проекта.Потому что я не задумывался об этом так глубоко раньше, ответа все еще нет.Поэтому поторопитесь и ознакомьтесь с ним, пока он еще горячий, и воспользуйтесь этой возможностью, чтобы разобраться в нем для каждый может пожевать.Каждый проект имеет свою ценность.Яркие пятна должны быть обнаружены любящими глазами 👁.
2. Что такое веб-сокет
WebSocket — это протокол для полнодуплексной связи по одному TCP-соединению. WebSocket упрощает обмен данными между клиентом и сервером, позволяя серверу активно передавать данные клиенту.
В API WebSocket браузеру и серверу нужно только выполнить рукопожатие, и между ними может быть установлено постоянное соединение, и может выполняться двусторонняя передача данных. (Википедия)
WebSocket по сути является计算机网络应用层的协议, используемый, чтобы компенсировать отсутствие постоянных коммуникационных возможностей протокола http.
Протокол WebSocket родился в 2008 году и стал международным стандартом в 2011 году. Теперь поддерживаются последние версии браузеров.
Его самая большая особенность заключается в том, что сервер может активно передавать информацию клиенту, а клиент также может активно отправлять информацию серверу.Это настоящий двусторонний равноправный диалог, который принадлежиттехнология push сервератипа.
Другие функции WebSocket включают в себя:
(1) Основываясь на протоколе TCP, реализация на стороне сервера относительно проста.
(2) Хорошая совместимость с протоколом HTTP. Порты по умолчанию также 80 и 443, а протокол HTTP используется на этапе рукопожатия, поэтому его нелегко экранировать во время рукопожатия, и он может проходить через различные прокси-серверы HTTP.
(3) Формат данных относительно легкий, производительность невелика, а связь эффективна.
(4) Можно отправлять текст, а также двоичные данные.
(5) Нет ограничений на одно и то же происхождение, и клиент может связываться с любым сервером.
(6) Идентификатор протоколаws(если зашифровано,wss), URL-адрес сервера — это URL-адрес.
ws://example.com:80/some/path
Зачем нужны веб-сокеты?
У нас уже есть протокол HTTP, зачем нам еще один протокол? Какую пользу это может принести?
Потому что у протокола HTTP есть изъян: связь может быть инициирована только клиентом и не имеет возможности протолкнуть сервер.
Например, если мы хотим узнать и запросить сегодняшние данные в реальном времени, только клиент отправляет запрос на сервер, а сервер возвращает результат запроса. Протокол HTTP не может позволить серверу активно передавать информацию клиенту.
Характеристики этого одностороннего запроса обречены быть очень неприятными для клиента, чтобы узнать, есть ли у сервера непрерывные изменения состояния. мы можем использовать только"опрос": время от времени отправляется запрос, чтобы узнать, есть ли на сервере новая информация. Самый типичный сценарий — чат. Опрос неэффективен и тратит ресурсы впустую (потому что вам нужно постоянно подключаться, иначе HTTP-соединение всегда открыто).
До появления протокола WebSocket создание веб-приложения с двухканальной связью с сервером требовало использования протокола HTTP для непрерывного опроса, что вызывало некоторые проблемы:
- Сервер вынужден поддерживать большое количество различных подключений от каждого клиента
- Большое количество запросов на опрос вызовет большие накладные расходы, такие как дополнительные заголовки, что приведет к бесполезной передаче данных.
Сам по себе протокол http не имеет возможности постоянной связи, но нам нужна эта возможность в практических приложениях, поэтому для решения этих проблем был создан протокол WebSocket, который в 2011 году был обозначен IETF как стандартный RFC6455. RFC7936.
И соответствующие API-интерфейсы, связанные с протоколом WebSocket, добавляются к стандарту HTML5, поэтому, пока клиентская сторона стандарта HTML5 реализована, может выполняться полнодуплексная постоянная связь с сервером, поддерживающим протокол WebSocket.
Разница между WebSocket и HTTP
Связь между WebSocket и HTTP:
Тот же пункт:Оба основаны на TCP и являются надежными транспортными протоколами. Оба являются протоколами прикладного уровня.
соединять:При установлении рукопожатия WebSocket данные передаются по протоколу HTTP. Но после установки протокол HTTP не нужен для реальной передачи.
Следующая диаграмма иллюстрирует основные различия между HTTP и WebSocket:
1. WebSocket — это протокол двусторонней связи, который имитирует протокол Socket и может отправлять или получать информацию в обоих направлениях, в то время как HTTP является односторонним; 2. WebSocket требует рукопожатия между браузером и сервером для установления соединения, а http — это соединение, инициированное браузером с сервером.
Примечание. Хотя HTTP/2 также имеет функцию отправки сервера, HTTP/2 может передавать только статические ресурсы и не может передавать указанную информацию.
3. Принцип работы протокола WebSocket
Как и протокол http, протокол WebSocket также требует установленного TCP-соединения для передачи данных. Конкретная реализация состоит в том, чтобы установить канал через протокол http, а затем использовать реальный протокол WebSocket для связи на этой основе, поэтому протокол WebSocket и протокол http имеют определенную взаимосвязь.
Прежде всего, WebSocket — это постоянный протокол, в отличие от HTTP, который является непостоянным протоколом. Давайте возьмем простой пример и объясним его на широко используемом жизненном цикле PHP.
Жизненный цикл HTTP определяется запросом, то есть одним запросом и одним ответом, затем в HTTP 1.0 этот HTTP-запрос заканчивается.
В HTTP 1.1 были внесены улучшения, так что есть поддержка активности, то есть в HTTP-соединении можно отправлять несколько запросов и получать несколько ответов. Но помните, что Запрос = Ответ, что всегда имеет место в HTTP, а это означает, что Запрос может иметь только один Ответ. И этот Ответ также пассивен и не может быть инициирован активно.
Прежде всего, WebSocket основан на протоколе HTTP или заимствует протокол HTTP для выполнения части рукопожатия.
Сначала давайте посмотрим на типичное рукопожатие WebSocket.
GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13
Origin: http://example.com
Дети, знакомые с HTTP, возможно, обнаружили, что в этом запросе рукопожатия так много вещей, похожих на протокол HTTP.
Upgrade: websocket
Connection: Upgrade
Это ядро WebSocket, скажите Apache, Nginx и другим серверам: Внимание, запрос, который я инициирую, использует протокол WebSocket, быстро помогите мне найти соответствующего помощника для обработки ~ не старомодного HTTP.
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13
Прежде всего, Sec-WebSocket-Key — это значение кодировки Base64, которое случайным образом генерируется браузером и сообщает серверу: торф, не обманывай меня, я хочу проверить, действительно ли ты помощник WebSocket.
Затем Sec_WebSocket-Protocol — это определяемая пользователем строка, используемая для различения протоколов, требуемых различными службами по одному и тому же URL-адресу. Простое понимание: я хочу служить сегодня вечером, не ошибитесь~
Наконец, Sec-WebSocket-Version сообщает черновик WebSocket (версию протокола), используемый сервером.В начале протокол WebSocket все еще находился на стадии черновика.Существуют всевозможные странные протоколы, и до сих пор возникает много странных проблем. Разные вещи, почему Firefox и Chrome используют разные версии и т.д. В начале было слишком много протоколов WebSocket, но это было большой проблемой. . Но теперь все в порядке, все улажено~ Все используют одну и ту же версию: Официант, я хочу 13-летнего →_→
Затем сервер вернет следующие вещи, указывающие на то, что запрос принят и WebSocket успешно установлен!
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=
Sec-WebSocket-Protocol: chat
Вот последняя область HTTP. Сообщите клиенту, что я успешно переключил протокол~
Upgrade: websocket
Connection: Upgrade
Все еще исправлено сообщение клиенту, что предстоящее обновление — это протокол WebSocket, а не mozillasocket, lurnarsocket или shitsocket.
Затем Sec-WebSocket-Accept — это ключ Sec-WebSocket-Key, подтвержденный сервером и зашифрованный. Сервер: Хорошо, понял, позвольте мне показать вам мое удостоверение личности, чтобы доказать это.
Последний, Sec-WebSocket-Protocol, является окончательным используемым протоколом.
На данный момент HTTP сделал всю свою работу, и следующим шагом будет полное следование протоколу WebSocket.
Суммировать,Процесс соединения WebSocket:
Сначала клиент инициирует http-запрос, и после трех рукопожатий устанавливается TCP-соединение, в http-запросе хранится такая информация, как номер версии, поддерживаемой WebSocket, например Upgrade, Connection, WebSocket-Version и т. д.;
Затем, после того как сервер получит запрос на установление связи от клиента, он также использует протокол HTTP для возврата данных;
Наконец, после того, как клиент получит сообщение об успешном соединении, он начинает осуществлять полнодуплексную связь посредством канала передачи TCP.
В-четвертых, преимущества и недостатки Websocket
преимущество:
- Как только предлагается протокол WebSocket, заголовок запроса, потребляемый взаимной связью, очень мал.
- Сервер может отправлять сообщения клиенту
недостаток:
- Небольшое количество браузеров не поддерживает его, а степень и метод поддержки браузерами разные (IE10)
Пятерки,Сценарии применения WebSocket
- мгновенное общение в чате
- многопользовательская игра
- Совместное онлайн-редактирование / редактирование
- Вытягивание и отправка потоков данных в реальном времени
- Спорт/игры в прямом эфире
- Расположение на карте в реальном времени
- немедленный
WebПрименение: МгновенноеWebприложение используетWebСокеты отображают данные на стороне клиента, которые постоянно отправляются внутренним сервером. существуетWebSocket, данные постоянно передаются/передача уже открыта для одного и того же соединения, поэтомуWebSocketПричина быстрее и повышает производительность приложений. Например, на торговом веб-сайте или при торговле биткойнами, которые являются наиболее изменчивыми, он используется для отображения колебаний цен, данные постоянно передаются клиенту внутренним сервером с использованием канала веб-сокета. - Игровые приложения: в игровых приложениях вы можете заметить, что сервер постоянно получает данные без обновления пользовательского интерфейса. Экранный пользовательский интерфейс обновляется автоматически, и нет необходимости устанавливать новые соединения, поэтому
WebSocketОчень помогает в игровых приложениях. - Приложение чата: Приложение чата использует только
WebSocketПосле установления соединения можно обмениваться сообщениями, публиковать их и транслировать между подписчиками. он повторно использует одно и то жеWebSocketСоединения для отправки и получения сообщений и взаимной передачи сообщений.
Сценарии, в которых нельзя использовать WebSocket
Если нам нужны какие-либо обновления в реальном времени или непрерывная потоковая передача данных по сети, мы можем использоватьWebSocket. Если мы хотим получить старые данные или просто хотим получить данные один раз для использования приложением, мы должны использоватьHTTPпротокол, данные, которые не нужно извлекать очень часто или только один раз, можно получить, простоHTTPзапрос запроса, поэтому лучше не использовать в этом случаеWebSocket.
Примечание. Если данные загружаются только один раз,RESTful WebСервису достаточно получить данные с сервера.
6. Отключение и повторное подключение через веб-сокет
Сердцебиение означает, что клиент регулярно отправляет сообщения на сервер, чтобы доказать, что клиент находится в сети.
Как судить онлайн и офлайн?
Когда клиент отправляет запрос на сервер в первый раз, он будет содержать уникальный идентификатор и метку времени.Сервер обращается к базе данных или кешу, чтобы запросить уникальный идентификатор запроса.Если он не существует, он будет сохранен в БД или кэше.
Во второй раз, когда клиент снова отправляет запрос через регулярные промежутки времени, он по-прежнему содержит уникальный идентификатор и временную метку.Сервер обращается к базе данных или кешу, чтобы запросить уникальный идентификатор измененного запроса.Если он существует, извлеките последнюю временную метку и вычесть текущую временную метку из текущей временной метки до последнего времени,
Полученное количество миллисекунд и секунд определяет, больше ли оно указанного времени.Если оно меньше указанного времени, он находится в сети, в противном случае - в автономном режиме;
Как исправить проблемы с отключением
Изучив информацию, я узнал, что при переадресации веб-сокета прокси-сервера nginx соединение без сообщения будет иметь проблему с отключением по тайм-ауту. В онлайн-информации упоминаются два решения: одно — изменить информацию о конфигурации nginx, а второе — отправить пакеты пульса через веб-сокет.
Подведем итог решения двух проблем отключения и переподключения вебсокета, решенных на практике данного проекта.
Активное срабатывание включает в себя активное отключение, и клиент активно отправляет сообщение серверу.
- Активно отключить
ws.close();
Активно отключайте, пользуйтесь по необходимости, а то редко.
- Активно отправлять сообщения
ws.send("hello world");
Давайте проанализируем отключение веб-сокета.
-
Возможные причины отключения 1: время ожидания веб-сокета истекло, а сообщение об автоматическом отключении соединения отсутствует.
В это время нам нужно знать продолжительность тайм-аута, установленную сервером.Существуют две схемы отправки пакетов пульса в течение периода тайм-аута: одна заключается в том, что клиент активно отправляет пакеты пульсации восходящей линии связи, а другая - что сервер активно отправляет пакеты нисходящей линии связи.
Далее в основном рассказывается о том, как клиент, то есть внешний интерфейс, реализует пакет сердцебиения:
Сначала разберитесь с механизмом пакетов сердцебиения
Причина, по которой пакет пропуска называется пакетом сердцебиения, заключается в том, что он отправляется каждый фиксированный момент времени, как сердцебиение, чтобы сообщить серверу, что клиент все еще жив. На самом деле это для поддержания длинного соединения.Что касается содержания этого пакета, то особого регламента нет, но это, как правило, небольшой пакет, либо пустой пакет, содержащий только заголовок пакета.
В механизме TCP есть механизм пакетов heartbeat, то есть опция TCP: SO_KEEPALIVE. Система по умолчанию использует установленную частоту сердцебиения, равную 2 часам. Но он не может проверить, выключена ли машина, отсоединен ли сетевой кабель и отключен ли брандмауэр. И логический уровень может не так хорошо обрабатывать разъединение. В общем, если его использовать только для поддержания жизни, то еще нормально.
Пакеты Heartbeat обычно реализуются путем отправки пустых эхо-пакетов на логическом уровне.
下一个定时器,在一定时间间隔下发送一个空包给客户端,然后客户端反馈一个同样的空包回来,服务器如果在一定时间内收不到客户端发送过来的反馈包,那就只有认定说掉线了。При длительном соединении может долго не происходить обмен данными. Теоретически это соединение всегда подключено, но на практике трудно узнать, выйдет ли из строя промежуточный узел. Хуже того, некоторые узлы (брандмауэры) автоматически отключают соединения, которые не взаимодействуют с данными в течение определенного периода времени. В настоящее время нам нужен наш пакет сердцебиения, чтобы поддерживать длительное соединение и оставаться в живых.
Этапы обнаружения сердцебиения:
- Клиент отправляет тестовый пакет на сервер каждый временной интервал
- Запустить таймер тайм-аута, когда клиент отправляет пакет
- Сторона сервера получает пакет обнаружения и должна ответить пакетом
- Если клиент получает ответный пакет от сервера, сервер работает нормально, а таймер тайм-аута удаляется.
- Если таймер тайм-аута клиента истекает, а ответный пакет все еще не получен, сервер вешает трубку.
// 前端解决方案:心跳检测 var heartCheck = { timeout: 30000, //30秒发一次心跳 timeoutObj: null, serverTimeoutObj: null, reset: function(){ clearTimeout(this.timeoutObj); clearTimeout(this.serverTimeoutObj); return this; }, start: function(){ var self = this; this.timeoutObj = setTimeout(function(){ //这里发送一个心跳,后端收到后,返回一个心跳消息, //onmessage拿到返回的心跳就说明连接正常 ws.send("ping"); console.log("ping!") self.serverTimeoutObj = setTimeout(function(){//如果超过一定时间还没重置,说明后端主动断开了 ws.close(); //如果onclose会执行reconnect,我们执行ws.close()就行了.如果直接执行reconnect 会触发onclose导致重连两次 }, self.timeout); }, this.timeout); } } -
Возможные причины отключения 2: исключения веб-сокетов включают прерывания сервера, интерактивные вырезания экрана и т. д. Аномальные прерывания клиента и т. д.
Когда сервер не работает, что должен делать клиент и что должен делать сервер, когда он снова подключается к сети?
Клиент должен отключиться и закрыть соединение через onclose.Когда сервер снова подключается к сети, ему необходимо очистить сохраненные данные.Если он не очищен, пока выполняется запрос на сервер, он будет считаться отключенным .
Решение прерывания для такого рода исключений заключается в обработке повторного подключения.Решение повторного подключения, которое мы приводим ниже, заключается в использовании библиотеки js для обработки: введите reconnecting-websocket.min.js, а метод установления связи ws использует метод API библиотеки js:
var ws = new ReconnectingWebSocket(url); // 断线重连: reconnectSocket(){ if ('ws' in window) { ws = new ReconnectingWebSocket(url); } else if ('MozWebSocket' in window) { ws = new MozWebSocket(url); } else { ws = new SockJS(url); } }Выкл. Библиотеки поддержки мониторинга сети с использованием JS: Offline.min.js
onLineCheck(){ Offline.check(); console.log(Offline.state,'---Offline.state'); console.log(this.socketStatus,'---this.socketStatus'); if(!this.socketStatus){ console.log('网络连接已断开!'); if(Offline.state === 'up' && websocket.reconnectAttempts > websocket.maxReconnectInterval){ window.location.reload(); } reconnectSocket(); }else{ console.log('网络连接成功!'); websocket.send("heartBeat"); } } // 使用:在websocket断开链接时调用网络中断监测 websocket.onclose => () { onLineCheck(); };Приведенные выше решения являются лишь руководством.Если у вас есть лучшее решение, поделитесь им в комментариях.
7. Резюме
- Websocket - это протокол для двухканальной связи в веб-приложениях. По сравнению с способом опроса HTTP-запросов, Websocket имеет преимущества сохранения ресурсов сервера и высокой эффективности.
- Маска в WebSocket настроена для предотвращения таких проблем, как атаки с загрязнением промежуточного кеша в более ранних версиях.Клиент должен отправлять данные на сервер, а сервер не должен отправлять данные клиенту.
- Алгоритм генерации Sec-WebSocket-Key в WebSocket заключается в объединении строк, сгенерированных сервером и клиентом, выполнении хеш-алгоритма SHA1 и последующем кодировании с помощью base64.
- Рукопожатие протокола WebSocket основано на протоколе HTTP и на ответе HTTP 101 для преобразования обновления протокола.
Ссылаться на :