Должен ли WebSocket.onclose инициироваться переходом пользователя или обновлением?

Часть 1: Ожидаемое поведение?

Я наблюдаю противоречивое поведение браузеров Firefox и Chrome в отношении вызываемого обработчика onclose.

Кажется, что Chrome не вызывает onclose, если это было вызвано навигацией/обновлением страницы пользователя. Однако Firefox вызывает onclose.

Мне кажется, что Firefox может вести себя здесь корректно:

Когда соединение WebSocket закрыто, возможно чисто, пользовательский агент должен создать событие, использующее интерфейс CloseEvent, с именем события close, которое не всплывающее окно, не может быть отменено, не имеет действия по умолчанию, чей атрибут wasClean имеет значение true, если соединение закрыто правильно, и false в противном случае, чей атрибут code установлен на код закрытия соединения WebSocket, а чей атрибут Reason установлен на закрытие соединения WebSocket причина; и поставьте в очередь задачу, чтобы сначала изменить значение атрибута readyState на CLOSED (3), а затем отправить событие объекту WebSocket.

Источник: http://www.w3.org/TR/2011/WD-websockets-20110419/#closeWebSocket

Несмотря на то, что это может привести к скрытому коду/неожиданному поведению.

Кто-нибудь может подтвердить ожидаемое поведение?

Часть 2: Как реализовать автоматическое переподключение?

Если у вас есть библиотека, которая автоматически переподключается для пользователя, как узнать, следует ли вам попытаться переподключиться? Проверяете ли вы свойствоCloseEvent.wasClean ? Я должен предположить, что «чистый» означает, что закрытие должно было произойти либо через вызов API WebSocket.close(), либо через сервер, отправляющий кадр закрытия? Если сетевая ошибка вызывает закрытие, я предполагаю, что wasCleanбудет false?

В библиотеке Pusher JavaScript мы предполагали (при закрытии -> ожидание -> подключение), что закрытие должно вызывать повторное подключение, если только мы не находимся в состоянии закрытия — разработчик решил закрыть соединение. Похоже, что клиентская библиотека socket.io делает то же предположение.

Исходя из этого, событие Firefox onclose, вызванное пользовательской навигацией/обновлением, запускает нежелательное повторное подключение, поскольку ни одна из библиотек не проверяет свойство CloseEvent.wasClean.

Пример и видео

Вот пример, который можно использовать для демонстрации несоответствия: http://jsbin.com/awonod/7

Вот видео, в котором я демонстрирую проблему: http://www.screenr.com/vHn8 (уже поздно, не обращайте внимания на пару оплошностей :))

Следует отметить, что мое нажатие клавиши Escape также могло привести к закрытию соединения WebSocket. Однако, если вы внимательно посмотрите или попробуете сами, вы увидите, что событие закрытия регистрируется непосредственно перед обновлением страницы.

32
задан leggetter 20 January 2017 в 10:45
поделиться