Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
357 views
in Technique[技术] by (71.8m points)

Why does my wss:// (WebSockets over SSL/TLS) connection immediately disconnect without giving any errors?

Posting this for anybody else running across the same problem.

I was working on a browser client that used stanza.io to connect to an XMPP server (Prosody, in my case). I was using a wss:// connection by default. At some point during development, my client failed to connect at all - it would immediately disconnect silently, without providing any kind of useful error information.

There were no error logs, no error codes, no confirmation dialogs or bars, no indications of what might be wrong.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

After hours of debugging, I eventually found the problem; as I was messing around with the configuration of my XMPP server, I had re-generated the SSL certificates for the XMPPd. Since I was using self-signed certificates, this would cause an SSL error. Because I had visited that same URI over HTTPS before, I'd already manually approved the old self-signed certificate - but obviously that approval was no longer valid after regenerating the SSL certificate.

The key to the problem is this: If your SSL certificate causes a warning of any sort, wss:// WebSocket connections will immediately fail, and there is no canonical way to detect this.

As stated above, there appears to be no standardized way to even detect that this problem is occurring, let alone solve it. The best solution to this problem that I have been able to find, is as follows:

  1. If the WebSocket disconnects prior to having received a login confirmation (XMPP-specific), try to make a plaintext ws:// (without SSL) connection to the non-SSL port.
  2. If the plaintext connection succeeds, this means that the server is up - thus the problem is with the SSL certificate. (If the plaintext connection also fails, the server is simply unavailable.)
  3. Display an error to the user, indicating that there was an SSL problem, and that they should check the certificate, with instructions on how to manually approve it.
  4. Provide a target="_blank" link to the wss:// URL, but replacing the protocol with https://. This might be Prosody-specific, but by visiting that URL you will see the SSL warning page. Prosody will display a text that starts with "It works!" after approving the certificate - if the server-side is a custom application, you should display a message saying that "the problem has been solved, you can close this tab now".
  5. In the background, in the main application, keep attempting to reconnect over wss:// every few seconds. Once a connection succeeds, this means the user has approved the certificate. Hide/remove the error and continue the normal connection/login process.

It's far from a smooth process, UX-wise, but it's the smoothest approach I've found. It is not possible to iframe the error page (this was one of my first ideas) - Chrome will refuse to load it at all, Firefox will hide the "Add exception" button, and I'd imagine other browsers exhibit similar behaviour.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...