2013-12-18 5 views
0

Я пытаюсь создать поток (HttpWorker), который при необходимости просыпается и отправляет HTTP-запрос. Я хотел бы, чтобы это было сделано в одном потоке. Я использую Qt для реализации.Передача потока HTTP-запроса с использованием Qt

Как я думал, я бы сделал это, чтобы иметь класс MyHttpWorker, переместить его в другой поток, подключить слоты/сигналы и т. Д. Затем в начале потока я бы использовал QNetworkAccessManager для вызова запросов на получение. Я бы использовал QWaitCondition, чтобы приостановить поток после отправки запроса, и я бы возобновил эту тему, когда мне нужно было отправить еще один.

Однако, когда я приостанавливаю поток httpworker, FinishedSlot вообще не вызывается. Если я использую класс для простого вызова одного HTTP-запроса, он выполняется без проблем. Поэтому проблема связана с QWaitCondition (или просто замораживанием потоков в целом).

Я мог бы просто создать и уничтожить одного работника и поток для каждого запроса, который у меня есть, но мне нужно отправить много http-запросов, поэтому я думаю, что этот метод будет слишком утомительным (создавая потоки и уничтожая их снова и снова) ,

Я ценю любую помощь, которую я могу получить.

Вот мой код:

MyHttpWorker.h

#include <QNetworkReply> 
#include <QDebug> 
#include <QObject> 
#include <QNetworkAccessManager> 
#include <QThread> 
#include <QWaitCondition> 
#include <QMutex>  

class MyHttpWorker : public QObject 
    { 
     Q_OBJECT 

     QNetworkAccessManager* nam;   
     QMutex syncPause; 
     QWaitCondition pauseCond;   

    public: 
     explicit MyHttpWorker(QObject *parent = 0);   
     void MyWake();    
    public slots:   
     void SetTheThread(QThread* thread); 
     void MyStart();   
     void finishedSlot(QNetworkReply* reply);    
    }; 

MyHttpWorker.cpp

MyHttpWorker::MyHttpWorker(QObject *parent) : 
    QObject(parent) 
{ 
    nam = new QNetworkAccessManager(this); 
    QObject::connect(nam, SIGNAL(finished(QNetworkReply*)), this, SLOT(finishedSlot(QNetworkReply*)));  
} 

void MyHttpWorker::finishedSlot(QNetworkReply* reply) 
{ 
    qDebug() << "Finished"; //This slot is never even reached, when i used QWaitCond... 
    if (reply->error() == QNetworkReply::NoError) 
    { 
     QByteArray bytes = reply->readAll(); 
     QString string(bytes); 
     qDebug() << string; 
    }else 
    { 
     qDebug() << reply->errorString(); 
    } 
    reply->deleteLater(); 
} 

void MyHttpWorker::SetTheThread(QThread* thread){ 
    QObject::connect(thread,SIGNAL(started()),this,SLOT(MyStart())); 
} 

void MyHttpWorker::MyWake(){  
    pauseCond.wakeAll(); 
} 

void MyHttpWorker::MyStart(){  
    qDebug() << "Start" ; 

    while(true){ 

     syncPause.lock();  
     qDebug() << "thread waiting..."; 
     pauseCond.wait(&syncPause); 
     qDebug() << "thread resumed."; 
     syncPause.unlock(); 

     //sending the actual request here 
     QNetworkRequest myRequest; 
     myRequest.setUrl(QUrl("http://www.google.com")); 
     nam->get(myRequest); 



    } 

} 

main.cpp

#include <QCoreApplication> 
#include <QThread> 
#include <QDebug> 
#include <myhttpworker.h> 

int main(int argc, char *argv[]) 
{ 
    QCoreApplication a(argc, argv); 

    //create the worker, thread and launch it... (worker is waiting by default) 
    MyHttpWorker* worker = new MyHttpWorker;  
    QThread* httpThread = new QThread;  
    worker->SetTheThread(httpThread); 
    worker->moveToThread(httpThread);  
    httpThread->start(); 

    //try and send 5 requests ... 
    for(int i=0;i<5;i++){ 
     qDebug() << "Unpausing";  
     QThread::currentThread()->msleep(1000);  
     worker->MyWake();  
    } 

    return a.exec(); 
} 

ответ

2

не создает бесконечный цикл, но пусть даже петля справиться с этим:

void MyHttpWorker::MyWake() 
{ 
    QMetaObject::invokeMethod(this,"doSend"); 
    //send to the event loop 
} 

// new slot 
void MyHttpWorker::doSend(){  
    //sending the actual request here 
    QNetworkRequest myRequest; 
    myRequest.setUrl(QUrl("http://www.google.com")); 
    nam->get(myRequest); 
} 
//and remove the myStart and all that synchronisation 

тогда, когда вы хотите, чтобы остановить его просто послать quit потока. Я предлагаю вам также подключить finished сигнал нити в deleteLater слот MyHttpWorker

+0

Он работает, спасибо :) Я просто хочу спросить, если вы могли бы clarifiy на «Я предлагаю вам подключить готовый сигнал нити слот deleteLater MyHttpWorker ". Ты потерял меня там. – Malisak

+0

в setTheThread, поэтому он удаляется, когда поток останавливается (что происходит только после того, как кто-то называет 'quit') –

+0

Ах да, конечно. Еще раз спасибо :) – Malisak