如何正确使用QStateMachine进行串行网络请求

时间:2019-05-21 14:09:59

标签: c++ qt network-programming fsm

我需要根据文本大小连续发出几个请求。我了解QEventLoop,但是我想避免使用嵌套循环,并且需要能够中止网络请求。因此,我决定根据评论中this的提示使用QStateMachine。

这是我的班级成员:

    QString m_text;
    QStateMachine *m_stateMachine;
    QNetworkAccessManager *m_networkManager;
    QPointer<QNetworkReply> m_currentReply; // Use QPointer to check if request was deleted.

在此功能中,我动态地构建我的状态机(通过分割文本以按部分进行请求):

void myClass::buildStateMachine()
{
    QString unsendedText = m_text;
    auto *nextTranslationState = new QState(m_stateMachine);
    m_stateMachine->setInitialState(nextTranslationState);

    while (!unsendedText.isEmpty()) {
        auto *currentTranslationState = nextTranslationState;
        nextTranslationState = new QState(m_stateMachine);

        const int splitIndex = getSplitIndex(unsendedText);
        auto *requestingState = new QState(currentTranslationState);
        requestingState->setProperty(myTextProperty, unsendedText.left(splitIndex)); // To get this text in requestData()
        connect(requestingState, &QState::entered, this, &MyClass::requestMethod);
        currentTranslationState->setInitialState(requestingState);
        currentTranslationState->addTransition(currentTranslationState, &QState::finished, nextTranslationState);

        // Remove the parsed part from the next parsing
        unsendedText = unsendedText.mid(splitIndex);
    }

    auto *finalTranslationState = new QFinalState(m_stateMachine);
    nextTranslationState->addTransition(finalTranslationState);
}

在此函数中,我发出请求:

void myClass::requestData()
{
    auto *requestingState = qobject_cast<QState *>(sender());
    QUrl url(...);

    m_currentReply = m_networkManager->get(QNetworkRequest(url));
    connect(m_currentReply, &QNetworkReply::finished, this, MyClass::parseData);
    connect(m_currentReply, &QNetworkReply::finished, &QNetworkReply::deleteLater);

    auto *finalState = new QFinalState(requestingState->parentState());
    requestingState->addTransition(m_currentReply, &QNetworkReply::destroyed, finalState);
}

这是一个好的解决方案吗?对我来说似乎很冗长。特别是如果我将嵌套状态用于嵌套网络请求(并且在子状态转换时也崩溃,我不知道如何调试它)。

0 个答案:

没有答案