[Перевод] Websocket Соглашение Глава 7 - Закрытые соединения (закрытие соединения)

WebSocket

Обзор

Эта статья является седьмой главой протокола WebSocket.Основной контент, переведенный в этой статье, связан с закрытием соединения WebSocket.

Учащиеся, которым интересно узнать о содержании предыдущих глав этого документа, могут увидеть:

закрыть соединение (тело протокола)

7.1 Определения

7.1.1 Закройте соединение WebSocket

хочу关闭 WebSocket 连接, терминал должен закрыть базовое TCP-соединение. Терминалы должны использовать метод для чистого закрытия соединения TCP и сеанса TLS, если это возможно, отбрасывая любые символы, которые могут следовать. Конечная точка может закрыть соединение любым способом, когда это необходимо, например, когда она получает атаку.

В базовом TCP-соединении, как правило, в большинстве случаев сервер должен закрыться первым, поэтому именно сервер, а не клиент поддерживает состояние TIME_WAIT (поскольку, если клиент закрывается первым, это не позволяет серверу повторно открыть его в течение 2 MSL. Если сервер находится в состоянии TIME_WAIT, при получении нового пакета SYN с большим порядковым номером он может немедленно ответить на повторное открытие соединения, так что это не повлияет на сервер). В нештатных случаях (например, по истечении разумного промежутка времени сервер получает пакет закрытия TCP) клиент ДОЛЖЕН начать закрытие TCP-соединения. Вот так, когда сервер входит关闭 WebSocket 连接состояние, он должен быть готов немедленно закрыть TCP-соединение, затем, когда клиент-клиент готов закрыть соединение, он должен дождаться пакета закрытия TCP от сервера.

Используя сокет Berkeley языка C в качестве примера, чтобы показать, как полностью закрыть соединение, на одном конце необходимо использоватьSHUP_WRпередачаshutdown()метод, вызовrecv()Пока не будет получено возвращаемое значение 0, указывающее, что противоположная сторона также готова закрыть соединение упорядоченным образом, а затем, наконец, вызватьclose()чтобы закрыть канал сокета.

7.1.2 Запуск рукопожатия закрытия WebSocket

с кодом состоянияcode(раздел 7.4) и необязательная причина отключенияreason(раздел 7.1.6) до开始 WebSocket 关闭握手, терминал ДОЛЖЕН отправить кадр закрытия, как описано в разделе 5.5.1, с кодом состояния, установленным наcodeполе, установить близкую причинуreaonsполе. После того, как терминал отправил и получил кадр управления отключением, терминал должен быть таким же, как определено в Разделе 7.1.1.关闭 WebSocket 连接.

7.1.3 Запущено рукопожатие закрытия WebSocket

Когда близкий кадр отправлен или получен, мы можем сказать已经开始 WebSocket 关闭握手, а состояние соединения WebSocket достигло состояния "ЗАКРЫТО".

7.1.4 Соединение WebSocket закрыто

Когда базовое TCP-соединение закрыто, мы можем сказатьWebSocket 连接已关闭, а соединение WebSocket достигло состояния "ЗАКРЫТО". Если TCP-соединение было закрыто после завершения рукопожатия закрытия WebSocket, то мы можем сказать, что соединение WebSocket было закрыто.彻底закрытие.

Если соединение WebSocket не установлено, мы также говоримWebSocket已经关闭,но нет彻底.

7.1.5 Код состояния закрытия WebSocket

Как определено в разделах 5.5.1 и 7.4, кадр выключения МОЖЕТ содержать код состояния выключения и указанную причину. Закрытие соединения WebSocket могло быть инициировано другой конечной точкой в ​​то же время.WebSocket 关闭状态码это код состояния, полученный приложением, реализующим этот протокол, в первом закрытом кадре, как определено в разделе 7.4. Если закрывающий фрейм не содержит кода состояния,WebSocket 关闭状态码по умолчанию 1005. еслиWebSocket 已经关闭и терминал не получает никаких близких кадров (например, базовое транспортное соединение может быть внезапно потеряно), тоWebSocket 关闭状态码по умолчанию 1006.

Примечание: два терминала могут неWebSocket 关闭状态码договориться о стоимости. Например: если удаленный конец отправляет кадр закрытия, но локальное приложение не считывает данные кадра закрытия из своего буфера сокета, а локальное приложение самостоятельно решает закрыть соединение и отправляет кадр закрытия, то обе конечные точки отправляют И будет получен закрытый кадр, в то время как близкие кадры больше отправляться не будут. Каждый терминал увидит сообщение, отправленное другим терминалом.WebSocket 关闭状态码код состояния. Таким образом, в этом примере возможно, что ни одна конечная точка никогда не согласовывалаWebSocket 关闭状态码, оба терминала одни примерно в одно и то же время开始 WebSocket 关闭握手.

7.1.6 Причины закрытия соединения WebSocket

Как определено в разделах 5.5.1 и 7.4, фрейм выключения может содержать код состояния, указывающий причину выключения, за которым следуют данные в кодировке UTF-8, которые анализируются таким образом, что терминал должен их интерпретировать, а не определен в этот протокол. Закрытие соединения WebSocket может быть запущено с другого конца в то же время.WebSocket 连接关闭原因представляет собой данные в кодировке UTF-8, содержащиеся в первом закрытом управляющем кадре, непосредственно следующем за кодом состояния (раздел 7.4), полученным приложением, реализующим протокол. Если таких данных в кадре близкого контроля нет, тоWebSocket 连接关闭原因Значение - пустая строка.

ПРИМЕЧАНИЕ. Как и в случае с логикой, упомянутой в 7.1.5, две конечные точки могут не согласоватьWebSocket 连接关闭原因.

7.1.7 Сбой соединения WebSocket

Некоторые алгоритмы и спецификации требуют, чтобы терминалыWebSocket 连接失效. Для этого клиент должен关闭 WebSocket 连接, и может сообщать о связанных проблемах пользователям подходящим способом (особенно о содержимом, полезном для разработчиков). Точно так же, чтобы добиться этого, сервер должен关闭 WebSocket 连接, и проблема должна быть зарегистрирована.

если раньшеWebSocket 已经建立连接, терминал должен позволитьWebSocket 连接失效, затем продолжаем关闭 WebSocket 连接Ранее терминалу необходимо было отправить код состояния, содержащий соответствующий статус (раздел 7.4). Когда терминал подтверждает, что другой конец не может получить или обработать закрывающий кадр, он может решить пропустить отправку закрывающего кадра, таким образом входя в нормальный процесс ошибки в начале и закрывая соединение WebSocket. терминал получаетWebSocket 连接失效После команды он не может продолжать попытки обработки данных с другого конца (включая закрывающий кадр ответа).

За исключением сценариев, упомянутых выше, и сценариев, указанных на уровне приложения (например, сценарий использует API WebSocket), клиент не должен закрывать соединение.

7.2 Аварийное отключение

7.2.1 Активное закрытие клиента

Некоторые специфические алгоритмы начального рукопожатия требуют, чтобы клиент разрешилWebSocket 连接失效.为了实现这些,客户端必须像第 7.1.7 节中定义的一样让WebSocket 连接失败。

Если базовое транспортное соединение на любом конце неожиданно потеряно, клиент ДОЛЖЕН разрешитьWebSocket 连接失败.

За исключением случаев, указанных выше, и ограничений прикладного уровня (например, сценариев, использующих API WebSocket), клиенту НЕ СЛЕДУЕТ закрывать соединение.

7.2.2 Активное отключение сервера

Некоторые алгоритмы требуют или рекомендуют сервер при запуске отслеживать рукопожатие соединения.终端 WebSocket 连接. Для этого сервер должен关闭 WebSocket 连接(Раздел 7.1.1).

7.2.3 Восстановление после аварийного завершения работы

Причин аварийного завершения работы множество. Примером может служить отключение из-за временной ошибки, в этом случае восстановление может привести к стабильному соединению и возобновлению нормальной работы. Некоторые проблемы также могут быть вызваны не временной проблемой. В этом случае, если каждый клиент сталкивается с аварийным завершением работы, клиент немедленно повторяет попытку подключения и продолжает работу без прерывания. Сервер может получить большое количество атак типа «отказ в обслуживании» от повторного подключения клиента. . Конечным результатом является то, что это решение может привести к невозможности своевременного восстановления службы или значительно затруднить восстановление службы.

Чтобы избежать этой проблемы, клиенты ДОЛЖНЫ использовать некоторые из альтернативных стратегий, определенных в этом разделе, когда ненормальный терминал пытается восстановить соединение.

Первая попытка восстановить соединение должна быть после случайного промежутка времени. Как выбрать параметры случайных событий, это решает клиент; выбор случайного значения от 0 до 5 секунд является разумной начальной задержкой, но клиент может выбрать другую длину в соответствии со своим собственным опытом и конкретными приложениями. задерживать.

Если первая повторная попытка подключения не удалась, задержку для последующих подключений следует увеличить, используя такие методы, как усеченная двоичная экспоненциальная отсрочка.Алгоритм отсрочки усеченного двоичного простого числа) и так далее, чтобы установить эту задержку.

7.3 Соединение корректно закрыто

Сервер может закрыть соединение WebSocket, когда захочет. Клиенты НЕ ДОЛЖНЫ произвольно закрывать соединения WebSocket. В любом случае терминал должен следовать开始 WebSocket 连接关闭Шаг.

7.4 Код состояния

При закрытии соединения (например, при отправке кадра закрытия после завершения начального квитирования) конечная точка может указать причину закрытия. Описание причин терминала для этого и действий, которые должен предпринять терминал, в этом документе не указаны. Этот документ предопределяет некоторые коды состояния и диапазоны кодов состояния, которые могут использоваться расширениями, платформами и конечными приложениями. Эти коды состояния и любые связанные с ними текстовые сообщения являются необязательными в закрытых фреймах.

7.4.1 Определение кодов состояния

При отправке закрытого кадра терминал может заранее определить следующие коды состояния.

1000

1000 указывает на плавное закрытие, означающее, что цель установления соединения достигнута.

1001

1001 означает, что терминал «ушел», например, сервер не работает или страница осталась в браузере.

1002

1002 означает, что терминал прервал соединение из-за ошибки протокола.

1003

1003 означает, что терминал закрыл соединение, потому что он получил данные неподдерживаемого типа данных (например, терминал может понимать только текстовые данные, но получил двоичные данные).

1004

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

1005

1005 является зарезервированным значением и не может использоваться терминалом в качестве кода состояния для закрытия кадра. Этот код состояния указывает приложению верхнего уровня, что в настоящее время код состояния отсутствует.

1006

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

1007

1007 указывает, что терминал закрыл соединение, поскольку он получил сообщение непоследовательного типа (например, текстовое сообщение, не закодированное в кодировке UTF-8).

1008

1008 указывает, что конечная точка закрыла соединение, так как получила сообщение о нарушении политики. Это общий код состояния, который может быть возвращен, если нет подходящего кода состояния (например, 1003 или 1009) или когда может потребоваться скрыть определенную информацию о политике.

1009

1009 указывает, что терминал закрыл соединение, так как получил слишком большое сообщение для обработки.

1010

1010 указывает, что терминал (клиент) должен согласовать одно или несколько расширений с сервером, но сервер не ответил на этот результат в рукопожатии WebSocket. Список необходимых расширений должен появиться в закрытой рамке.原因(reason)в поле.

1001

1001 означает, что сервер закрыл соединение из-за непредвиденной ситуации, из-за которой он не смог выполнить запрос.

1015

1015 является зарезервированным значением и не может быть установлено терминалом в код состояния закрытого кадра. Этот код состояния используется приложениями верхнего уровня, чтобы указать, что сбой соединения был закрыт из-за неудачного рукопожатия TLS (например, сертификат сервера не был проверен).

7.4.2 Зарезервированный диапазон кодов состояния

0-999

Коды состояния 0-999 не используются.

1000-2999

Код состояния 1000-2999 — это зарезервированное поле, определенное в этом документе, будущих версиях и расширениях для постоянно доступных общедоступных документов.

3000-3999

Коды состояния 3000-3999 зарезервированы для библиотек, фреймворков и приложений. Эти коды состояния регистрируются непосредственно IANA. Эти коды состояния не объясняются в этом документе.

4000-4999

Коды состояния 4000-4999 зарезервированы для частного использования, поэтому эти коды состояния нельзя зарегистрировать. Эти коды состояния можно использовать в протоколах, предшествующих приложениям WebSocket. Эти коды состояния не объясняются в этом документе.