Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/qt/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Qt中使用QNetworkAccessManager的持久连接_Qt_Qnetworkaccessmanager_Qnetworkrequest - Fatal编程技术网

在Qt中使用QNetworkAccessManager的持久连接

在Qt中使用QNetworkAccessManager的持久连接,qt,qnetworkaccessmanager,qnetworkrequest,Qt,Qnetworkaccessmanager,Qnetworkrequest,我正在尝试使用Qt维护客户端和远程服务器之间的持久连接。我的身体很好。我在Qt中做我的客户端。这里我将使用QNetworkAccessManager来请求带有get方法的服务器(属于QNetworkRequest方法的一部分)。我将能够发送和接收请求 但经过一段时间(约2分钟)客户端通知服务器后,连接已通过自动发布请求而关闭。我想QNetworkAccessManager正在为此连接设置超时。我想保持两端之间的持久连接 我的方法正确吗?如果不正确,有人能引导我走正确的道路吗?这个问题很有趣,所以

我正在尝试使用Qt维护客户端和远程服务器之间的持久连接。我的身体很好。我在Qt中做我的客户端。这里我将使用
QNetworkAccessManager
来请求带有get方法的服务器(属于
QNetworkRequest
方法的一部分)。我将能够发送和接收请求

但经过一段时间(约2分钟)客户端通知服务器后,连接已通过自动发布请求而关闭。我想
QNetworkAccessManager
正在为此连接设置超时。我想保持两端之间的持久连接


我的方法正确吗?如果不正确,有人能引导我走正确的道路吗?

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

QApplication a(argc, argv);
QNetworkAccessManager manager;
QNetworkRequest r(QUrl("http://myserver/"));
manager.get(r);
return a.exec();
我还使用以下命令(在Linux控制台中)监视连接并检查问题是否再次出现:

watch -n 1 netstat -n -A inet
我快速查看了Qt源代码,发现它使用了
qtcsocket
,并在
QHttpNetworkConnectionChannel::close
中关闭它。所以我打开了调试器控制台(
窗口)→ 意见→ 调试器日志(Qt Creator中的
),并在进程暂停时添加了断点:

bp QAbstractSocket::close
注意:这是针对cdb(MS调试器),其他调试器需要其他命令。另一个注意事项:我使用带有调试信息的Qt,没有它,这种方法可能无法工作

经过两分钟的等待,我得到了
close()
调用的回溯

QAbstractSocket::close  qabstractsocket.cpp 2587    0x13fe12600 
QHttpNetworkConnectionPrivate::~QHttpNetworkConnectionPrivate   qhttpnetworkconnection.cpp  110 0x13fe368c4 
QHttpNetworkConnectionPrivate::`scalar deleting destructor' untitled        0x13fe3db27 
QScopedPointerDeleter<QObjectData>::cleanup qscopedpointer.h    62  0x140356759 
QScopedPointer<QObjectData,QScopedPointerDeleter<QObjectData>>::~QScopedPointer<QObjectData,QScopedPointerDeleter<QObjectData>> qscopedpointer.h    99  0x140355700 
QObject::~QObject   qobject.cpp 863 0x14034b04f 
QHttpNetworkConnection::~QHttpNetworkConnection qhttpnetworkconnection.cpp  1148    0x13fe35fa2 
QNetworkAccessCachedHttpConnection::~QNetworkAccessCachedHttpConnection untitled        0x13fe1e644 
QNetworkAccessCachedHttpConnection::`scalar deleting destructor'    untitled        0x13fe1e6e7 
QNetworkAccessCachedHttpConnection::dispose qhttpthreaddelegate.cpp 170 0x13fe1e89e 
    QNetworkAccessCache::timerEvent qnetworkaccesscache.cpp 233 0x13fd99d07 
(next lines are not interesting)
并且
ExpiryTime=120
是硬编码的


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

根据定义,2分钟的超时连接符合持久连接的条件。我的意思是,如果它不是持久的,你就必须在每次请求时重新连接。与其他一些软件相比,2分钟是相当慷慨的。但在一段时间的不活动之后,它最终会超时,这是一件不应该令人惊讶的好事。一些软件允许更改超时时间,但根据Pavel的调查,在Qt的情况下,超时时间似乎是硬编码的


幸运的是,解决方案很简单,只需安装一个计时器,每隔1分钟左右发送一次心跳(只是一个虚拟请求,不要与“心跳网络”混淆),以保持连接的活力。在使用连接之前,请停用计时器,连接完成后,请重新启动计时器。

这个问题对我来说似乎非常有效。如果你找到了解决方案,你介意和社区分享吗?还请提供一些代码片段,以便工程师可以轻松地帮助您。为什么不实现发送心跳以保持连接活动?如果您的服务器支持WebSocket,您可能希望检查客户端和服务器之间的持久连接。Cameron,感谢您的参考,但是工程师对网络管理器的可能性非常挑剔。你对此有什么想法吗?@ddrive,任何链接都肯定会有帮助,非常感谢。
node->timestamp = QDateTime::currentDateTime().addSecs(ExpiryTime);