Обзор
Популярность мини-программ и мини-игр WeChat сделала применение WebSocket повсеместным. В ответ на эту тему автор намерен создать серию блогов с целью представить WebSocket и узнать, как быстро создавать и использовать возможности, предоставляемые WebSocket в Springboot и JS.
В эту серию планов входят следующие статьи:
Первое, что такое WebSocket и для чего он используется.
Вторая статья, как использовать STOMP для быстрой сборки режима широковещательных сообщений WebSocket в Spring
Третья статья в Springboot о том, как использовать WebSocket и STOMP для быстрого создания режима двухточечных сообщений (1)
Четвертая часть, в Springboot, как использовать WebSocket и STOMP для быстрого создания режима сообщений точка-точка (2)
Пятая статья в Springboot реализует собственный агент сообщений WebSocket для веб-чатов.
Шестая статья в Springboot реализует более гибкий WebSocket.
Основная линия этой статьи
Сначала из типичного сценария выбирается сценарий спроса WebSocket, а затем объясняется сам протокол WebSocket. Включая его определение, характеристики и интерпретацию сообщения процесса рукопожатия. Наконец, снова изРазмер протоколаиКак реализовать длинное соединениеВ двух аспектах сравниваются сходства и различия между HTTP и WebSocket, что позволяет читателям глубже понять и понять WebSocket.
Соответствующие читатели этой статьи
Чтобы позаботиться о новичках, не знакомых с фронтенд/бэкэнд разработкой, в качестве первой статьи серии в этой статье используется более подробный метод интерпретации с целью продвижения от более мелкого к более глубокому. Последующие главы будут обновляться и запускаться одна за другой, так что следите за обновлениями.
начать со сцены
Сяомин купил билет.За несколько часов до вылета он надеется использовать программное обеспечение для динамических запросов рейсов, чтобы узнать динамику рейсов в режиме реального времени, например, есть ли задержки, отмены и другую информацию.
Затем программное обеспечение запросов взаимодействует с сервером, как показано ниже:
Нетрудно понять, что для каждого динамического запроса полета клиенту необходимо инициировать запрос к серверу, а затем ждать ответа от сервера. Когда клиент получает ответ, жизненный цикл этого сообщения объявляется завершенным.Но Сяомин сказал:Я надеюсь запросить статус рейса только один раз. Когда рейс обновляется, сервер может активно отправлять мне последнюю информацию о статусе рейса!
что делать? Умный программист придумал следующий способ:
- Метод опроса (например, опрос ajax)
То есть, когда Сяомин делает первый запрос внутри программы, информация о запросе и информация об ответе записываются, а сервер запрашивается каждое фиксированное время (например, 1 минута), и сервер возвращает текущий последний статус и сравнивает информация, полученная ранее.Если есть какие-либо изменения, Xiaomi будет уведомлен;
Клиент: Есть какие-нибудь новости (Запрос)
Сервер: снять нормально (Ответ)
Клиент: ля-ля-ля, есть новости? (Запрос)
Сервер: Взлететь нормально. . (Ответ)
Клиент: Есть какие-нибудь новости (Запрос)
Сервер: Ты такой надоедливый, снимай нормально. . (Ответ)
Клиент: Есть какие-нибудь новости (Запрос)
Сервер: Ладно, ладно, у меня для вас задержка 30 минут. . (Ответ)
Клиент: Есть какие-нибудь новости (Запрос)
Сервер: Нет. . . (Ответ)
- Сервер добавляет отложенный ответ (длинное соединение)
Эта программа по-прежнему использует внутренний опрос, но по сравнению с более чем одной программой используйте режим блокировки. (Был звонок, не получил, не положил трубку), то есть клиент инициирует соединение, если сервер не новость, он не вернул ответ клиенту. Пока нет новостей, прежде чем уведомлять Сяомин, после подключения клиента снова и снова.
Клиент: Есть какие-нибудь новости, если нет, то просто ждите, когда они вернутся ко мне (Запрос)
Сервер: Я скажу вам, когда будет что-то динамичное. (Через некоторое время) Вот, вот, 30 минут задержки (Ответ)
Клиент: Есть какие-нибудь новости, если нет, то просто ждите, когда они вернутся ко мне (Запрос)
С точки зрения всего процесса взаимодействия эти двое очень ресурсоемки.
- Для первого варианта, опроса, требуется сервер с высокой скоростью обработки и ресурсами процессора. (обученный оператор)
- Второе решение, длинное HTTP-соединение (будет представлено позже), требует высокого параллелизма, то есть возможности параллельной обработки. (достаточно операторов)
Таким образом, все они могут сделать следующее:
Клиент: Есть новости?
Сервер: слишком много людей спрашивают, линия занята, повторите попытку позже (503 сервер недоступен)
Клиент: . . . . Хорошо, что нового?
Сервер: слишком много людей спрашивают, линия занята, повторите попытку позже (503 сервер недоступен)
Клиент: . . . . Можно ли это сделать на стороне сервера? . !@#$%$^&
В приведенном выше примере мы видим, что эти два способа использования HTTP не являются лучшим способом, что отражено в:
- Пассивность HTTP: Требует много сервисных ресурсов. Нужны «операторы» с более высокой скоростью, и нужно больше «операторов». И то, и другое приведет к увеличению спроса на сервисные ресурсы (операторы).
- Безгражданство HTTP: Поскольку оператор только отвечает на звонки и обрабатывает запрос, он не записывает, кто им звонил.Каждый раз, когда вы звоните, вы должны сообщить оператору, кто вы и какой у вас запрос.
Итак, что мне теперь делать, если я хочу выполнить требования Сяо Мина?
Настоящее тело WebSocket
После стольких разговоров давайте приступим к делу. На основе вышеуказанных требований и противоречий появился WebSocket.
Давайте сначала посмотрим, как будет выглядеть приведенный выше сценарий после использования WebSocket:
Клиент: я хочу начать использовать протокол WebSocket, необходимая служба: чат (проверьте динамический), версия протокола WebSocket: 13 (HTTP-запрос)
Сервер: нет проблем, он был обновлен до протокола WebSocket (переключение протоколов HTTP)
Клиент: Пожалуйста, пришлите мне push-уведомление, когда статус рейса будет обновлен.
Сервер: Нет проблем.
(...прошло 10 минут)
Сервер: Есть новости, задержка 30 минут!
(...прошло 30 минут)
Сервер: Есть новости, начинайте посадку прямо сейчас!
Отсюда видно, что
- При использовании WebSocket сервер может активно проталкивать информацию клиенту, не беспокоясь о том, как долго клиент будет ждать, и не беспокоясь о тайм-ауте и отключении, что решает проблему пассивности.
- Websocket требуется только одно HTTP-взаимодействие для переключения протокола. Весь процесс связи устанавливается в одном соединении/состоянии, что позволяет избежать отсутствия состояния HTTP. Сервер всегда будет знать вашу информацию, пока вы не закроете запрос. Это решает проблему, которую сервер должен повторно анализировать заголовок HTTP-запроса.
Как показано ниже:
Рождение веб-сокета
WebSocket — это спецификация протокола, предложенная HTML5 (2011 г.) со ссылкой на протокол:
The WebSocket Protocol RFC6455
WebSocket определяет спецификацию связи.Через механизм рукопожатия между клиентом (например, браузером) и сервером (веб-сервером) может быть установлено Tcp-подобное соединение, тем самым облегчая связь между C-S.
Особенности протокола WebSocket
- Основываясь на протоколе TCP, он должен обмениваться данными через соединение с подтверждением связи, и реализация на стороне сервера относительно проста.
- Он имеет хорошую совместимость с протоколом HTTP. Порт по умолчанию также 80 или 443, а протокол HTTP используется на этапе рукопожатия, поэтому его нелегко экранировать во время рукопожатия, и он может проходить через различные прокси-серверы HTTP.
- Формат данных относительно легкий, производительность невелика, а связь эффективна. Можно отправлять текст, а также двоичные данные.
- Ограничений по одному и тому же источнику нет, и клиенты могут взаимодействовать с произвольными серверами.
- Идентификатор протокола — ws (или wss, если он зашифрован), а URL-адрес сервера — это URL-адрес. (Пример: ws://www.example.com/chat)
- Это протокол двусторонней связи, который использует асинхронные обратные вызовы для получения сообщений. Когда коммуникационное соединение установлено, может быть установлено постоянное соединение. И сервер WebSocket, и браузер могут активно отправлять или получать данные друг другу. метод — это активная отправка сервером, пока есть данные, они будут отправлены запрашивающей стороне.
Используйте диаграмму, чтобы описать взаимосвязь каждого протокола:
Установление связи WebSocket - процесс рукопожатия
Рукопожатие WebSocket реализовано с использованием HTTP, и клиент отправляет сообщение HTTP-запроса с заголовком Upgrade. Сервер отвечает в соответствии с запросом.
Сообщение запроса:
GET wss://www.example.cn/webSocket HTTP/1.1
Host: www.example.cn
Connection: Upgrade
Upgrade: websocket
Sec-WebSocket-Version: 13
Origin: http://example.cn
Sec-WebSocket-Key: afmbhhBRQuwCLmnWDRWHxw==
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits
Объясните подробно:
- Строки 1 и 2: Как и в строке запроса HTTP-запроса, здесь используется протокол HTTPS, поэтому он соответствует запросу wss.
- строка 3:Connection: HTTP1.1 указывает, что Upgrade можно использовать только в прямых соединениях. Сообщение HTTP1.1 с заголовком Upgrade должно содержать заголовок Connection, поскольку смысл заголовка Connection заключается в том, что любой, кто получает это сообщение (обычно прокси-сервер), должен обработать домен, указанный в Connection, перед пересылкой сообщения (т.е. Upgrade поля не пересылаются).
- строка 4: Обновление — это поле заголовка, используемое для определения протокола преобразования в HTTP1.1. Клиент хочет использовать установленное соединение HTTP (TCP) и переключиться на протокол WebSocket, если сервер его поддерживает.
- строка 5: Sec-WebSocket-Version определяет список версий протокола WebSocket, поддерживаемых клиентом.
- строка 6: Origin безопасно используется для предотвращения межсайтовых атак. Браузеры обычно используют это для идентификации исходного домена.
- строка 7: Sec-WebSocket-Key — это значение в кодировке Base64, которое генерируется клиентом случайным образом и используется для проверки сервера.Сервер будет использовать это поле, чтобы собрать другое значение ключа и отправить его клиенту в ответном сообщении рукопожатия.
- строка 8: Sec_WebSocket-Protocol — это определяемая пользователем строка, используемая для различения протоколов, требуемых различными службами по одному и тому же URL-адресу, и идентифицирующая список подпротоколов, поддерживаемых клиентом.
- строка 9: Sec-WebSocket-Extensions — это поле, используемое клиентом для согласования протокола расширения с сервером, permessage-deflate указывает, следует ли использовать сжатие передаваемых данных при согласовании, а client_max_window_bits указывает размер SIZE, относящийся к скользящему окну, когда LZ77 используется алгоритм сжатия.
Примечание. Если вас интересуют подробности согласования компандирования, обратитесь к RFC7692 ниже для получения более подробной информации.Compression Extensions for WebSocket RFC7692
Ответное сообщение:
HTTP/1.1 101
Server: nginx/1.12.2
Date: Sat, 11 Aug 2018 13:21:27 GMT
Connection: upgrade
Upgrade: websocket
Sec-WebSocket-Accept: sLMyWetYOwus23qJyUD/fa1hztc=
Sec-WebSocket-Protocol: chat
Sec-WebSocket-Extensions: permessage-deflate;client_max_window_bits=15
Объясните подробно:
- линия 1: версия HTTP — HTTP1.1, код возврата — 101, и начинается анализ поля заголовка (без учета регистра).
- строка 2,3: информация о сервере и время.
- строка 4: Поле подключения, включая Upgrade.
- строка 5: Поле обновления, включая веб-сокет.
- строка 6: Поле Sec-WebSocket-Accept, представьте подробно:
Этапы генерации поля Sec-WebSocket-Accept:
- Объедините Sec-WebSocket-Key с идентификатором GUID «258EAFA5-E914-47DA-95CA-C5AB0DC85B11», определенным в протоколе.
- SHA1 кодирует строку, сгенерированную на шаге 1.
- Base64 кодирует строку, сгенерированную на шаге 2.
Клиент определяет две вещи, проверяя значение Sec-WebSocket-Accept, возвращаемое сервером:
- Понимает ли сервер протокол WebSocket, если сервер не понимает, то он не вернет правильный Sec-WebSocket-Accept, и установление соединения WebSocket не удастся.
- Ответ, возвращаемый сервером, относится к запросу клиента, а не к предыдущему кешу. В основном для того, чтобы некоторые кеш-серверы не возвращали кешированные ответы.
- строка 7: Поле Sec-WebSocket-Protocol, чтобы определить, имеет ли предыдущее рукопожатие запроса этот протокол, если нет, соединение не установлено.
- строка 8: Расширенное согласование протокола, поддержка сжатия и размер скользящего окна LZZ — 15.
На этом процесс рукопожатия завершен, и TCP-соединение в это время не будет разорвано. Клиент и сервер могут общаться друг с другом.
Сходства и различия между HTTP1.1 и WebSocket
Наконец, в качестве заключения, давайте рассмотрим сходства и различия между HTTP 1.1 и WebSocket. Углубите свое понимание WebSocket.
Сходства и различия на уровне протокола
Та же точка
- Оба являются протоколами прикладного уровня, основанными на TCP.
- Оба используют модель запроса/ответа для установления соединения.
- Точно так же обрабатываются ошибки при установлении соединения, и на этом этапе WebSocket может возвращать тот же код возврата, что и HTTP.
разница
- Протокол HTTP основан на запросе/ответе и может выполнять только одностороннюю передачу.Это полудуплексный протокол, а WebSocket – полнодуплексный протокол.Подобно сокетной связи, обе стороны могут отправлять данные другой стороне в в любой момент.
- WebSocket использует HTTP для установления соединений, но определяет ряд новых полей заголовков, которые не используются в HTTP. Другими словами, заголовки запросов у них разные.
- Соединение WebSocket не может быть переадресовано через посредника, это должно быть прямое соединение. При пересылке через прокси-сервер прокси должен выдерживать такое количество соединений WebSocket, не освобождая его, что похоже на DDOS-атаку.
- Когда WebSocket устанавливает рукопожатие, данные передаются по HTTP-протоколу, но после установления соединения реальная фаза передачи данных не требует участия HTTP-протокола.
- Данные, передаваемые WebSocket, представляют собой двоичный поток, а единицей измерения является кадр.HTTP передает передачу открытого текста, то есть передачу строки.Кадр данных WebSocket упорядочен.
Сходства и различия между длинным соединением HTTP и постоянным соединением WebSocket
Два длинных соединения HTTP
1. Постоянное соединение используется по умолчанию для соединений HTTP1.1.
То есть для поддержания соединения в течение определенного промежутка времени клиенту потребуется запросить у сервера большое количество ресурсов за короткий промежуток времени, чтобы не допустить разрыва TCP-соединения. Клиент связывается с сервером, клиент должен инициировать, а сервер возвращает результат. Клиент активен, а сервер пассивен. По одному TCP-соединению может быть передано несколько пар сообщений «запрос/ответ», поэтому, по сути, они по-прежнему являются парами сообщений «запрос/ответ», что по-прежнему будет приводить к трате ресурсов и снижению производительности в реальном времени. Если это не постоянное соединение, то есть короткое соединение, то каждый ресурс должен устанавливать новое соединение.Нижний уровень HTTP использует TCP, тогда каждый раз для установления соединения TCP используется трехстороннее рукопожатие, т.е. , каждому запросу соответствует ответ, что приведет к огромной трате ресурсов.
2. «Длинный опрос»
То есть клиент отправляетдолгий тайм-аутЗапрос, сервер поддерживает соединение и возвращает ответ при поступлении новых данных
Постоянные соединения для WebSockets
Его нужно только для создания пары сообщений запроса / ответа. Сохраните много транспортных и серверов ресурсов. Поэтому он широко используется в разработке онлайн веб-игр и онлайн-чатов.
Следующие перспективы контента
В следующей статье автор будет использовать JS (внешняя часть) и Springboot (внутренняя часть), чтобы подробно рассказать, как использовать среду Springboot для быстрого создания простой системы связи WebSocket на основе STOMP. быть в курсе.
Произведено Сяомином, это должен быть бутик
Добро пожаловать на технический форум xNPE, ежедневно появляется все больше оригинальных галантерейных товаров.