我可以使用QNetworkCookieJar
来检索,存储和重新发送QNetworkManager
的Cookie。多个QNetworkAccessManager
个实例可以共享一个QNetworkCookieJar
。
到目前为止,我已经使用了多个QNetworkAccessManager
个实例,每个类一个(我需要阅读的地方):
QNetworkCookieJar
个实例中共享一个单QNetworkAccessManager
QNetworkAccessManager
,其中一个Jar在所有QNetworkRequest
中共享。 QNetworkAccessManager
作为单个对象的方式是什么?文档说应该只有一个实例。那么我最好使用单身QNetworkAccessManager
吗? 最合适的方式是什么?
------编辑-------
kkoehne's answer从我能说的是正确的。这也是文档所说的。但是,在尝试这种方法时,我注意到了两个问题:
QNetworkAccessManager
,但更改为一个单一实例意味着我需要始终区分我刚刚收到的"已完成" slot(从QNetworkAccessManager::finished
调用的那个)。这是可行的,但不方便。QNetworkAccessManager
的单个实例,因为成员函数是reentrant,但不是线程安全的。 (QNetworkAccessManager from ThreadPool)相关:QNetworkAccessManager get/post from different thread possible?
答案 0 :(得分:1)
我认为您指的是QNetworkAccessManager
,而不是QNetworkManager
。
您应该更喜欢在您的应用中使用一个QNetworkAccessManager
。这不仅消除了同步QNetworkCookieJar
的任何需要,而且还确保最佳地利用网络,并且共享缓存的内容等。
正如您自己注意到的那样,这也在QtNetworkAccessManager documentation中暗示:
对于整个Qt,一个QNetworkAccessManager应该足够了 应用
答案 1 :(得分:1)
这是我所做的(并且似乎有效):
QNetworkAccessManager
。QNetworkCookieJar
不是一个选项,因为它不是线程安全但是创建我自己的小线程安全 - 派生自QNetworkCookieJar
- 类很容易。我只需要担心5个虚函数。我可以在QNetworkAccessManager
之间分享这个线程安全的cookie罐。
我在这里遇到了一定的风险,因为QObject
的其他公共成员函数不是线程安全的并且可能会崩溃,但这些似乎并没有在那个用例中使用。
请求的示例代码:
/*!
* Cookie manager, which allows thread safe sharing of cookies
*/
class BLACKCORE_EXPORT CCookieManager : public QNetworkCookieJar
{
Q_OBJECT
public:
//! Constructor, only allowed from BlackCore::CApplication
CCookieManager(BlackMisc::Restricted<CApplication>, QObject *parent = nullptr);
//! \copydoc QNetworkCookieJar::setCookiesFromUrl
//! \threadsafe
virtual bool setCookiesFromUrl(const QList<QNetworkCookie> &cookies, const QUrl &url) override;
//! \copydoc QNetworkCookieJar::cookiesForUrl
//! \threadsafe
virtual QList<QNetworkCookie> cookiesForUrl(const QUrl &url) const override;
//! Cookies for request
//! \threadsafe
QList<QNetworkCookie> cookiesForRequest(const QNetworkRequest &request) const;
//! \copydoc QNetworkCookieJar::deleteCookie
//! \threadsafe
virtual bool deleteCookie(const QNetworkCookie &cookie) override;
//! Delete all cookies
//! \threadsafe
void deleteAllCookies();
//! \copydoc QNetworkCookieJar::insertCookie
//! \threadsafe
virtual bool insertCookie(const QNetworkCookie &cookie) override;
//! \copydoc QNetworkCookieJar::updateCookie
//! \threadsafe
virtual bool updateCookie(const QNetworkCookie &cookie) override;
private:
mutable QReadWriteLock m_lock { QReadWriteLock::Recursive };
};
CCookieManager::CCookieManager(BlackMisc::Restricted<CApplication>, QObject *parent) : QNetworkCookieJar(parent)
{
// code
}
bool CCookieManager::setCookiesFromUrl(const QList<QNetworkCookie> &cookies, const QUrl &url)
{
QWriteLocker l(&m_lock);
return QNetworkCookieJar::setCookiesFromUrl(cookies, url);
}
QList<QNetworkCookie> CCookieManager::cookiesForUrl(const QUrl &url) const
{
QReadLocker l(&m_lock);
const QList<QNetworkCookie> cookies(QNetworkCookieJar::cookiesForUrl(url));
return cookies;
}
QList<QNetworkCookie> CCookieManager::cookiesForRequest(const QNetworkRequest &request) const
{
return cookiesForUrl(request.url());
}
bool CCookieManager::deleteCookie(const QNetworkCookie &cookie)
{
QWriteLocker l(&m_lock);
return QNetworkCookieJar::deleteCookie(cookie);
}
bool CCookieManager::insertCookie(const QNetworkCookie &cookie)
{
QWriteLocker l(&m_lock);
return QNetworkCookieJar::insertCookie(cookie);
}
bool CCookieManager::updateCookie(const QNetworkCookie &cookie)
{
QWriteLocker l(&m_lock);
return QNetworkCookieJar::updateCookie(cookie);
}
void CCookieManager::deleteAllCookies()
{
QWriteLocker l(&m_lock);
this->setAllCookies(QList<QNetworkCookie>());
}