Qt中使用QNetworkAccessManager的持久连接

vgo*_*129 5 qt qnetworkaccessmanager qnetworkrequest

我正在尝试使用Qt维护客户端和远程服务器之间的持久连接.我的服务方面很好.我在Qt做客户端.在这里,我将用于使用QNetworkAccessManagerget方法请求服务器(QNetworkRequest方法的一部分).我将能够发送和接收请求.

但是在一段时间(大约2分钟)之后,客户端正在暗示服务器,通过自动发布请求来关闭连接.我想QNetworkAccessManager是为这个连接设置超时.我想在两端之间保持持久的联系.

我的方法是否正确,如果没有,有人可以引导我走正确的道路吗?

Pav*_*hov 4

这个问题很有趣,我们来研究一下。我设置了一个具有较大保持活动超时的 nginx 服务器,并编写了最简单的 Qt 应用程序:

\n\n
QApplication a(argc, argv);\nQNetworkAccessManager manager;\nQNetworkRequest r(QUrl("http://myserver/"));\nmanager.get(r);\nreturn a.exec();\n
Run Code Online (Sandbox Code Playgroud)\n\n

我还使用以下命令(在 Linux 控制台中)来监视连接并检查问题是否再次出现:

\n\n
watch -n 1 netstat -n -A inet\n
Run Code Online (Sandbox Code Playgroud)\n\n

我快速查看了 Qt 源代码,发现它使用QTcpSocket并关闭了它QHttpNetworkConnectionChannel::close。因此,我打开调试器控制台(Window \xe2\x86\x92 Views \xe2\x86\x92 Debugger log在 Qt Creator 中)并在进程暂停时添加了一个断点:

\n\n
bp QAbstractSocket::close\n
Run Code Online (Sandbox Code Playgroud)\n\n

注意:这适用于 cdb(MS 调试器),其他调试器需要其他命令。另请注意:我使用带有调试信息的 Qt,如果没有它,这种方法可能无法工作。

\n\n

等了两分钟后,我收到了电话的回溯close()

\n\n
QAbstractSocket::close  qabstractsocket.cpp 2587    0x13fe12600 \nQHttpNetworkConnectionPrivate::~QHttpNetworkConnectionPrivate   qhttpnetworkconnection.cpp  110 0x13fe368c4 \nQHttpNetworkConnectionPrivate::`scalar deleting destructor\' untitled        0x13fe3db27 \nQScopedPointerDeleter<QObjectData>::cleanup qscopedpointer.h    62  0x140356759 \nQScopedPointer<QObjectData,QScopedPointerDeleter<QObjectData>>::~QScopedPointer<QObjectData,QScopedPointerDeleter<QObjectData>> qscopedpointer.h    99  0x140355700 \nQObject::~QObject   qobject.cpp 863 0x14034b04f \nQHttpNetworkConnection::~QHttpNetworkConnection qhttpnetworkconnection.cpp  1148    0x13fe35fa2 \nQNetworkAccessCachedHttpConnection::~QNetworkAccessCachedHttpConnection untitled        0x13fe1e644 \nQNetworkAccessCachedHttpConnection::`scalar deleting destructor\'    untitled        0x13fe1e6e7 \nQNetworkAccessCachedHttpConnection::dispose qhttpthreaddelegate.cpp 170 0x13fe1e89e \n    QNetworkAccessCache::timerEvent qnetworkaccesscache.cpp 233 0x13fd99d07 \n(next lines are not interesting)\n
Run Code Online (Sandbox Code Playgroud)\n\n

负责此操作的类是QNetworkAccessCache。它设置计时器并确保其对象在QNetworkAccessCache::Node::timestamp过去时被删除。这些对象是 HTTP 连接、FTP 连接和凭据。

\n\n

接下来,什么是timestamp?当对象被释放时,其时间戳按以下方式计算:

\n\n
node->timestamp = QDateTime::currentDateTime().addSecs(ExpiryTime);\n
Run Code Online (Sandbox Code Playgroud)\n\n

并且ExpiryTime = 120是硬编码的。

\n\n

所有涉及的课程都是私人的,我找不到办法阻止这种情况的发生。因此,每分钟发送一次保持活动请求会更简单(至少现在您知道 1 分钟足够安全),因为替代方法是重写 Qt 代码并编译自定义版本。

\n