Правильное закрытие WebSocket (HTML5, Javascript) - PullRequest
114 голосов
/ 27 января 2011

Я играю с HTML5 WebSockets.Мне было интересно, как изящно закрыть соединение?Например, что произойдет, если пользователь обновит страницу или просто закроет браузер?

Существует странное поведение, когда пользователь просто обновляет страницу, не вызывая websocket.close() - когда он возвращается после обновления, он попадает в окно.websocket.onclose событие.

Ответы [ 5 ]

92 голосов
/ 27 января 2011

В соответствии со спецификацией протокола v76 (это версия, которую реализует браузер с текущей поддержкой):

Чтобы правильно закрыть соединение, фрейм, состоящий всего из 0xFFБайт, за которым следует байт 0x00, отправляется одним узлом, чтобы попросить другого узла закрыть соединение.

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

Браузер должен действительно сделать это за вас, когда вы закрываете или перезагружаете страницу.Тем не менее, вы можете убедиться, что закрытый фрейм отправлен, выполнив захват события beforeunload:

window.onbeforeunload = function() {
    websocket.onclose = function () {}; // disable onclose handler first
    websocket.close();
};

Я не уверен, как вы можете получить событие onclose после обновления страницы.Объект websocket (с обработчиком onclose) больше не будет существовать после перезагрузки страницы.Если вы сразу пытаетесь установить соединение WebSocket на своей странице при загрузке страницы, возможно, у вас возникла проблема, когда сервер отказывает в новом соединении вскоре после того, как старое отключилось (или браузер не готовустановить соединение в точке, в которой вы пытаетесь подключиться), и вы получаете событие onclose для нового объекта websocket.

34 голосов
/ 01 декабря 2011

Дело в том, что сегодня используются две основные версии протоколов WebSockets.Старая версия, которая использует протокол [0x00][message][0xFF], а затем новая версия, использующая пакеты в формате Hybi .

Старая версия протокола используется Opera и iPod / iPad / iPhones, поэтомуНа самом деле важно, чтобы в серверах WebSockets была реализована обратная совместимость.В этих браузерах, использующих старый протокол, я обнаружил, что обновление страницы, переход от страницы или закрытие браузера приводят к тому, что браузер автоматически закрывает соединение.Отлично !!

Однако в браузерах, использующих новую версию протокола (например, Firefox, Chrome и, в конечном итоге, IE10), только закрытие браузера приведет к тому, что браузер автоматически закроет соединение.То есть, если вы обновите страницу или уйдете со страницы, браузер НЕ автоматически закроет соединение.Однако, что делает браузер, так это отправляет пакет hybi на сервер с первым байтом (идентификатор протока), равным 0x88 (более известным как закрытый фрейм данных).Как только сервер получит этот пакет, он может принудительно закрыть само соединение, если вы того пожелаете.

34 голосов
/ 27 января 2011

Очень просто, вы закрываете его:)

var myWebSocket = new WebSocket("ws://example.org"); 
myWebSocket.send("Hello Web Sockets!"); 
myWebSocket.close();

Вы также проверяли следующий сайт И проверяли вводную статью об Opera

3 голосов
/ 17 января 2015

Как уже упоминалось theoobe , некоторые браузеры не закрывают веб-сокеты автоматически. Не пытайтесь обрабатывать какие-либо события «закрыть окно браузера» на стороне клиента. В настоящее время нет надежного способа сделать это, если учесть поддержку основных мобильных браузеров для настольных ПК И (например, onbeforeunload не будет работать в Mobile Safari). У меня был хороший опыт решения этой проблемы на стороне сервера. Например. если вы используете Java EE, взгляните на javax.websocket.Endpoint , в зависимости от браузера будет вызываться либо метод OnClose, либо метод OnError, если вы закроете / перезагрузите окно браузера.

2 голосов
/ 19 июня 2018

Используя метод close веб-сокета, где вы можете написать любую функцию в соответствии с требованиями.

var connection = new WebSocket('ws://127.0.0.1:1337');
    connection.onclose = () => {
            console.log('Web Socket Connection Closed');
        };
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...