我正在开发一个Qt应用程序,它通过WebSocket与我的网络浏览器(目前为Google Chrome)进行通信。
一切正常,直到我尝试使用安全的 websockets......
我设法解决了我在OpenSSL上遇到的问题,所以现在我应该有一个有效的Qt应用程序,但我没有。
我使用的是VS2013和Qt 5.3。我有以下代码来启动我的服务器:
MyClass::MyClass (quint16 port, QObject *parent) :
QWebSocketServer("Press And Listen Server", QWebSocketServer::SecureMode, parent) {
QSslConfiguration sslConfiguration;
QFile certFile (QStringLiteral ("localhost.crt"));
QFile keyFile (QStringLiteral ("localhost.key"));
certFile.open (QIODevice::ReadOnly);
keyFile.open (QIODevice::ReadOnly);
QSslCertificate certificate (&certFile, QSsl::Pem);
QSslKey sslKey (&keyFile, QSsl::Rsa, QSsl::Pem);
certFile.close ();
keyFile.close ();
sslConfiguration.setPeerVerifyMode (QSslSocket::VerifyNone);
sslConfiguration.setLocalCertificate (certificate);
sslConfiguration.setPrivateKey (sslKey);
sslConfiguration.setProtocol (QSsl::TlsV1SslV3);
this->setSslConfiguration (sslConfiguration);
if (!this->listen (QHostAddress::Any, port)) {
throw ServerNotStartedException () ;
}
qDebug () << "Server listenning on: " << port ;
connect (this, &QWebSocketServer::newConnection, this, &MyClass::onNewConnection);
connect (this, &QWebSocketServer::closed, this, &MyClass::onClose);
connect (this, &QWebSocketServer::sslErrors, this, &MyClass::onSslErrors);
}
我使用以下方法创建了证书文件:https://developer.salesforce.com/blogs/developer-relations/2011/05/generating-valid-self-signed-certificates.html
在浏览器方面,我只有:
var websock = websock = new WebSocket('wss://localhost:52132');
websock.onerror = function (error) {
console.log('Press & Listen, WS Error: ' + error);
};
websock.onopen = function () {
console.log('Open!');
};
不幸的是,每次我尝试时,我都会收到以下JS消息:
WebSocket connection to 'wss://localhost:52132/' failed: Error in connection establishment: net::ERR_TIMED_OUT
迄今:
-
QSslSocket::supportsSsl ()
返回true
- 我没有任何
QSslSocket: cannot resolve XXX method
消息 加载OpenSSL DLL,VS2013输出以下消息:
"MyProject.exe"(Win32):已加载"I:\Sources\VS2013\x64\Release\ssleay32.dll"。找不到或打开 PDB 文件。'PressAndListenQt.exe' (Win32): 已加载 'I:\Sources\VS2013\x64\Release\libeay32.dll'.找不到或打开 PDB 文件。
我不知道如何找到问题所在,所以我愿意接受任何建议!
编辑:我尝试使用以下方法(而不是上面的链接)生成自签名证书:
openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 100 -nodes
现在我得到另一个错误:
WebSocket connection to 'wss://localhost:52132/' failed: WebSocket opening handshake was canceled
根据您的问题陈述
- OpenSSL库似乎还可以
- Qt代码和Html代码可能没问题
- 缺少 安全服务器
Qt \Examples\Qt-5.x\websockets\sslechoserver 中有一个示例代码,也是一个带有 websocket html 代码的 html 文件。如果我们运行上面的示例并查看 web-socket 回复,它将给出错误代码 1006 错误代码。
我已经查看了发生的错误,我认为这可能是因为您没有在安全的Web服务器(非https)上托管html代码。我建议您在网络服务器上托管您的html文件,并将其与您的证书映射以进行https安全浏览。
连接终止可能是因为套接字不安全或证书不匹配。
浏览器控制台
WebSocket connection to 'wss://localhost:1234/' failed: Error in connection establishment: net::ERR_INSECURE_RESPONSE
URL 请求的浏览器跟踪
t=11880 [st= 0] +REQUEST_ALIVE [dt=17]
t=11880 [st= 0] URL_REQUEST_DELEGATE [dt=1]
t=11881 [st= 1] +URL_REQUEST_START_JOB [dt=16]
--> load_flags = 18 (BYPASS_CACHE | DISABLE_CACHE)
--> method = "GET"
--> priority = "LOWEST"
--> url = "wss://localhost:1234/"
t=11881 [st= 1] URL_REQUEST_DELEGATE [dt=0]
t=11881 [st= 1] HTTP_CACHE_GET_BACKEND [dt=0]
t=11881 [st= 1] +HTTP_STREAM_REQUEST [dt=15]
t=11881 [st= 1] HTTP_STREAM_REQUEST_STARTED_JOB
--> source_dependency = 6025 (HTTP_STREAM_JOB)
t=11896 [st=16] HTTP_STREAM_REQUEST_BOUND_TO_JOB
--> source_dependency = 6025 (HTTP_STREAM_JOB)
t=11896 [st=16] -HTTP_STREAM_REQUEST
t=11896 [st=16] URL_REQUEST_DELEGATE [dt=1]
t=11897 [st=17] CANCELLED
--> net_error = -501 (ERR_INSECURE_RESPONSE)
t=11897 [st=17] -URL_REQUEST_START_JOB
--> net_error = -501 (ERR_INSECURE_RESPONSE)
t=11897 [st=17] URL_REQUEST_DELEGATE [dt=0]
t=11897 [st=17] -REQUEST_ALIVE
Http 流的浏览器跟踪
t=11881 [st= 0] +HTTP_STREAM_JOB [dt=15]
--> alternative_service = "unknown :0"
--> original_url = "wss://localhost:1234/"
--> priority = "LOWEST"
--> source_dependency = 6024 (URL_REQUEST)
--> url = "wss://localhost:1234/"
t=11881 [st= 0] +PROXY_SERVICE [dt=0]
t=11881 [st= 0] PROXY_SERVICE_RESOLVED_PROXY_LIST
--> pac_string = "DIRECT"
t=11881 [st= 0] PROXY_SERVICE_DEPRIORITIZED_BAD_PROXIES
--> pac_string = "DIRECT"
t=11881 [st= 0] -PROXY_SERVICE
t=11881 [st= 0] +SOCKET_POOL [dt=15]
t=11896 [st=15] SOCKET_POOL_BOUND_TO_CONNECT_JOB
--> source_dependency = 6026 (CONNECT_JOB)
t=11896 [st=15] SOCKET_POOL_BOUND_TO_SOCKET
--> source_dependency = 6029 (SOCKET)
t=11896 [st=15] -SOCKET_POOL
--> net_error = -202 (ERR_CERT_AUTHORITY_INVALID)
t=11896 [st=15] HTTP_STREAM_JOB_BOUND_TO_REQUEST
--> source_dependency = 6024 (URL_REQUEST)
t=11896 [st=15] -HTTP_STREAM_JOB
前我似乎也发生了同样的事情。我解决了将自签名证书信任到证书管理单元中的问题您可以使用 MMC 控制台打开。将证书导入到当前用户的个人和本地计算机文件夹中,将证书也导入到受信任的发布者文件夹中。请记住在测试后删除证书。
您也可以对教程 Qt\Examples\Qt-5.5\websockets\sslechoserver\ 的 localhost.cert 证书进行相同的操作,并查看 websockets 网页如何与本教程提供的 wss 连接。
当网页中的 websocket 无法连接并出现相同错误时,这对我有用。
(对不起,我的英语:)低)
尝试将 url 从 wss://localhost:52132 修改为 https:// 或 http://。作为猜测,防火墙和服务器可能会拒绝 wss://因为它是自定义协议。