¿Por qué mi conexión wss://(WebSockets over SSL/TLS) se desconecta inmediatamente sin dar ningún error?
xmpp (2)
Publicar esto para cualquier otra persona que se encuentre con el mismo problema.
Estaba trabajando en un cliente de navegador que utilizaba stanza.io para conectarse a un servidor XMPP (Prosody, en mi caso). Estaba usando una conexión wss: // por defecto. En algún momento durante el desarrollo, mi cliente no se conectó en absoluto; se desconectaría de forma inmediata y silenciosa, sin proporcionar ningún tipo de información de error útil.
No hubo registros de errores, ni códigos de error, ni cuadros de diálogo ni barras de confirmación, ni indicios de lo que podría estar mal.
Después de horas de depuración, finalmente encontré el problema; como estaba jugando con la configuración de mi servidor XMPP, había vuelto a generar los certificados SSL para XMPPd. Como estaba usando certificados autofirmados, esto causaría un error de SSL. Como había visitado el mismo URI a través de HTTPS anteriormente, ya había aprobado manualmente el antiguo certificado autofirmado, pero obviamente esa aprobación ya no era válida después de regenerar el certificado SSL.
La clave del problema es esta: si su certificado SSL causa una advertencia de cualquier tipo, las conexiones wss://
WebSocket fallarán inmediatamente, y no hay una forma canónica de detectar esto.
Como se indicó anteriormente, parece que no existe una forma estandarizada para detectar que este problema está ocurriendo, y mucho menos resolverlo . La mejor solución a este problema que he podido encontrar es la siguiente:
- Si WebSocket se desconecta antes de haber recibido una confirmación de inicio de sesión (específica de XMPP), intente realizar una conexión de texto sin formato
ws://
( sin SSL ) al puerto que no es SSL. - Si la conexión de texto claro tiene éxito, significa que el servidor está activo, por lo que el problema es con el certificado SSL. (Si la conexión de texto sin formato también falla, el servidor simplemente no está disponible).
- Muestre un error al usuario, indicando que hubo un problema de SSL, y que debería verificar el certificado, con instrucciones sobre cómo aprobarlo manualmente.
- Proporcione un enlace
target="_blank"
a la URLwss://
, pero reemplazando el protocolo conhttps://
. Esto podría ser específico de Prosody, pero al visitar esa URL verá la página de advertencia de SSL. Prosody mostrará un texto que comienza con "¡Funciona!" después de aprobar el certificado, si el lado del servidor es una aplicación personalizada, debe mostrar un mensaje que diga que "el problema se ha resuelto, puede cerrar esta pestaña ahora". - En segundo plano, en la aplicación principal, sigue intentando volver a conectar en wss: // cada pocos segundos. Una vez que una conexión tiene éxito, esto significa que el usuario ha aprobado el certificado. Oculte / elimine el error y continúe con el proceso normal de conexión / inicio de sesión.
Está lejos de ser un proceso sencillo, en cuanto a UX, pero es el enfoque más sencillo que he encontrado. No es posible iframear la página de error (esta fue una de mis primeras ideas) - Chrome se negará a cargarla en absoluto, Firefox ocultará el botón "Agregar excepción", y me imagino que otros navegadores muestran un comportamiento similar.
Recuerde que a los navegadores modernos no les gustan los certificados autofirmados. Por lo tanto, si su conexión segura a WebSocket
muere antes de finalizar el intercambio, puede significar que el certificado no ha sido aceptado. Para resolver el problema, puedes:
- comprar un certificado firmado por una Autoridad central
- simplemente abra en una nueva pestaña o ventana el enlace de su URI de WebSocket y diga al navegador que confíe en la conexión. Regrese a su WebSocket y debería funcionar.