Почему соединение wss://(WebSockets over SSL/TLS) немедленно отключается без каких-либо ошибок?

Проводка этого для другого, выполняющего ту же проблему.

Я работал над клиентом браузера, который использовал stanza.io для подключения к серверу XMPP (в моем случае - Prosody). Я использовал соединение wss://по умолчанию. В какой-то момент во время разработки мой клиент вообще не смог подключиться - он немедленно отключился без каких-либо полезных сведений об ошибке.

Не было никаких журналов ошибок, кодов ошибок, никаких диалогов подтверждения или баров, никаких указаний на то, что может быть неправильным.

Ответы

Ответ 1

После нескольких часов отладки я в конце концов обнаружил проблему; поскольку я возился с конфигурацией моего сервера XMPP, я повторно создал SSL-сертификаты для XMPPd. Поскольку я использовал самозаверяющие сертификаты, это приведет к ошибке SSL. Поскольку я ранее посещал тот же URI по HTTPS, я уже вручную утвердил старый самозаверяющий сертификат, но, очевидно, что это утверждение больше недействительно после восстановления сертификата SSL.

Ключом к проблеме является следующее: Если ваш SSL-сертификат вызывает предупреждение любого типа, wss:// Соединения WebSocket будут немедленно завершены, и нет никакого канонического способа обнаружить это.

Как указано выше, не существует стандартизованного способа даже обнаружить, что эта проблема возникает, не говоря уже о ее решении. Лучшим решением этой проблемы, которую я смог найти, является следующее:

  • Если WebSocket отключится до получения подтверждения входа в систему (для XMPP-специфики), попробуйте сделать соединение с открытым текстом ws:// (без SSL) с не-SSL-портом.
  • Если соединение с открытым текстом завершается успешно, это означает, что сервер завершен - поэтому проблема связана с сертификатом SSL. (Если соединение с открытым текстом также терпит неудачу, сервер просто недоступен.)
  • Отобразить ошибку пользователю, указывая на наличие проблемы с SSL, и чтобы они проверяли сертификат, с инструкциями о том, как его одобрить вручную.
  • Укажите ссылку target="_blank" на URL wss://, но замените протокол на https://. Это может быть специфично для Prosody, но, посетив этот URL-адрес, вы увидите страницу предупреждения SSL. Просодия отобразит текст, который начинается с "Это работает!". после утверждения сертификата - если серверная сторона является настраиваемым приложением, вы должны показать сообщение о том, что "проблема решена, вы можете закрыть эту вкладку сейчас".
  • В фоновом режиме, в основном приложении, продолжайте пытаться повторно подключиться через wss://каждые несколько секунд. Как только соединение будет успешным, это означает, что пользователь одобрил сертификат. Скрыть/удалить ошибку и продолжить нормальный процесс подключения/входа.

Это далеко не гладкий процесс, UX-мудрый, но это самый плавный подход, который я нашел. Невозможно iframe страницы с ошибкой (это было одной из моих первых идей) - Chrome откажется загружать его вообще, Firefox скроет кнопку "Добавить исключение", и я бы предположил, что другие браузеры демонстрируют подобное поведение.

Ответ 2

Помните, что современные браузеры не любят самозаверяющие сертификаты. Поэтому, если ваше безопасное соединение WebSocket умирает до окончания рукопожатия, это может означать, что сертификат не был принят. Чтобы решить проблему, вы можете:

  • купить сертификат, подписанный центральным органом.
  • просто открывается в новом Вкладка или Окно ссылку на ваш URI WebSocket и сообщить браузеру доверяйте соединению. Вернитесь в свой WebSocket, и он должен работать.