繁体   English   中英

在Qt应用程序中共享Cookie的最佳方法

[英]Best way to share cookies within Qt application

我可以使用QNetworkCookieJar检索,存储和重新发送QNetworkManager cookie。 多个QNetworkAccessManager实例可以共享一个QNetworkCookieJar

到目前为止,我已经使用了多个QNetworkAccessManager实例,每个类一个(我需要在其中读取):

  1. 所以我可以在1..n QNetworkAccessManager实例之间共享一个单例QNetworkCookieJar
  2. 或者,最好是在所有QNetworkRequest共享一个带有一个Jar的单例QNetworkAccessManager QNetworkAccessManager是单个对象吗? 文档说应该只有一个实例。 所以我最好使用单例QNetworkAccessManager吗?

什么是最合适的方式?

------编辑-------

所知,kkoehne的答案是正确的。 这也是文档所说的。 但是,在尝试这种方法时,我注意到了两个问题:

  1. 现在我们每个Web服务都有一个QNetworkAccessManager ,但是更改为一个实例意味着我需要始终区分我刚刚在“完成”插槽(从QNetworkAccessManager::finished调用)中收到的内容。 这是可行的,但不方便。
  2. 我们以不同的方式来运作读者-不幸的是,我忘记在问题中提及这一点。 这使得几乎不可能使用QNetworkAccessManager的单个实例,因为成员函数是可重入的 ,但不是线程安全的。 ThreadPool的QNetworkAccessManager

相关: QNetworkAccessManager可以从不同的线程获取/发布吗?

我假设您指的是QNetworkAccessManager ,而不是QNetworkManager

您应该在应用程序中最好有一个QNetworkAccessManager 这不仅摆脱了同步QNetworkCookieJar的任何需求,而且还确保了网络的最佳利用,并且共享了缓存的内容等。

如您所知,QtNetworkAccessManager 文档中也暗示了这一点:

一个QNetworkAccessManager对于整个Qt应用程序应该足够了。

这是我所做的(似乎可行):

  1. 当我们在线程中阅读时,我无法使用单个QNetworkAccessManager
  2. 不能共享QNetworkCookieJar ,因为它不是线程安全的

但是创建我自己的微型线程安全类(从QNetworkCookieJar派生)很容易。 我只需要担心5个虚拟功能。 我可以在QNetworkAccessManager之间共享该线程安全cookie jar。

我在这里冒着一定的风险,因为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>());
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM