为什么我的wss://(基于SSL/TLS的WebSockets)连接立即断开而不显示任何错误?

35

发表此文是为了帮助遇到同样问题的人。

我正在开发一个浏览器客户端,使用stanza.io连接到一个XMPP服务器(在我的情况下是Prosody)。我默认使用了wss://连接。在开发过程中的某一点上,我的客户端根本无法连接 - 它会立即默默地断开连接,没有提供任何有用的错误信息。

没有错误日志,没有错误代码,没有确认对话框或状态栏,也没有任何可能出错的迹象。

3个回答

49
经过数小时的调试,我最终发现了问题。我在配置我的XMPP服务器时搞砸了,我重新生成了XMPPd的SSL证书。由于我使用的是自签名证书,这将导致SSL错误。因为我之前已经通过HTTPS访问相同的URI并手动批准了旧的自签名证书,但是显然在重新生成SSL证书后该批准不再有效。
问题的关键是:如果SSL证书引起任何警告,wss:// WebSocket连接将立即失败,并且没有统一的方法来检测此问题。 如上所述,似乎没有标准化的方法来检测此问题是否正在发生,更不用说解决它了。我能够找到的最佳解决方案如下:
  1. 如果在接收到登录确认之前WebSocket断开连接(特定于XMPP),请尝试在非SSL端口上进行纯文本ws://没有SSL)连接。
  2. 如果纯文本连接成功,则表示服务器正常工作 - 因此问题出在SSL证书上。(如果纯文本连接也失败,则服务器不可用。)
  3. 向用户显示错误,指示存在SSL问题,并要求他们检查证书,并提供手动批准证书的说明。
  4. 提供一个target="_blank"链接到wss:// URL,但将协议替换为https://。这可能是特定于Prosody的,但通过访问该URL,您将看到SSL警告页面。 Prosody在批准证书后会显示以“It works!”开头的文本 - 如果服务器端是自定义应用程序,则应显示一条消息,指出“问题已经解决,现在可以关闭此选项卡”。
  5. 在主应用程序中,背景下每隔几秒钟尝试重新连接wss://。一旦连接成功,就表示用户已经批准了证书。隐藏/删除错误并继续正常的连接/登录过程。

从用户体验角度来看,这并不是一个很流畅的过程,但这是我找到的最流畅的方法。无法在iframe中加载错误页面(这是我的第一个想法之一)- Chrome将拒绝完全加载它,Firefox将隐藏“添加异常”按钮,我想其他浏览器也会表现出类似的行为。


我自己也遵循了同样的方法,但我正在寻找解决这个问题的方法。你已经找到解决这个问题的方法了吗? - Sahil
@user3522412 我不知道自从我发布答案以来有什么变化。看起来我们仍然被困在这个问题上... - Sven Slootweg
我按照第四步骤,直接将其粘贴到地址栏中,结果发现我的证书未经授权(尽管它在我的另一台Web服务器上可以正常工作)。非常感谢这些好的提示!!! - Hai Nguyen

3

请记住,现代浏览器不喜欢自签名证书。因此,如果您的安全WebSocket连接在握手结束之前中断,可能意味着证书未被接受。

  • 购买由中央机构签名的证书
  • 只需在新的选项卡或窗口中打开您的WebSocket URI链接,并告诉浏览器信任该连接。然后返回到您的WebSocket,它应该可以正常工作。

2

请确保在 openssl req ... -nodes 命令中使用 -nodes 选项,否则生成的密钥文件将会被加密,服务器无法读取 key.pem 文件。 - Asad-ullah Khan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接