Часть 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
?
В библиотеке JavaScript Pusher мы предполагали (onclose -> ожидание -> подключение), что закрытие должно вызывать повторное подключение, если только мы не находимся в состоянии закрытия — разработчик решил закрыть соединение. Похоже, что клиентская библиотека socket.io делает то же предположение.
Исходя из этого, событие Firefox onclose, вызванное пользовательской навигацией/обновлением, запускает нежелательное переподключение, поскольку ни одна из библиотек не проверяет свойство CloseEvent.wasClean
.
Пример и видео
Вот пример, который можно использовать для демонстрации несоответствия: http://jsbin.com/awonod/7.
Вот видео, в котором я демонстрирую проблему: http://www.screenr.com/vHn8 (уже поздно , не обращайте внимания на пару ляпов :))
Следует отметить, что мое нажатие клавиши Escape также может привести к закрытию соединения WebSocket. Однако, если вы внимательно посмотрите или попробуете сами, вы увидите, что событие закрытия регистрируется непосредственно перед обновлением страницы.