Буду рад если кто-то поделится исходниками на эту тему, очень интересно посмотреть.
А что именно интересует?
В том, чтобы самому писать, ничего сложного нет!
Я просто из тех людей которые пока не увидят код, ничего не поймут.
Просто интересует распределенная много-поточная отправка http запросов.
Вот примерчик. Набор классов для выполнения разных типов запросов с разными параметрами. Примеры использования:
GET:
WebGetRequest *g = new WebGetRequest(QUrl("http://www.google.ru"),"./check_internet.xml");
connect(g,SIGNAL(done(WebReply)),this,SLOT(check_internet_done(WebReply)));
connect(g,SIGNAL(offline()),this,SLOT(internet_offline()));
g->run();
QFile file("C:/image.jpeg");
file.open(QIODevice::ReadOnly);
QByteArray data = file.readAll();
file.close();
WebPostRequest *p = new WebPostRequest(QUrl("http://send.photo.here.com"),"image/jpeg",data,data.size(),"answer.xml");
connect(p,SIGNAL(done(WebReply)),this,SLOT(send_image_done(WebReply)));
connect(p,SIGNAL(offline()),this,SIGNAL(not_connected()));
p->run();
Elfinit, спасибо большое, про http я уже досконально изучил, просто интересно как это правильней всего с потоками выглядит.
Я посмотрел класс, очень интересный пример.
Если у кого еще есть что-нибудь буду очень благодарен.
сегодня тоже провозился пол-дня. Пытался сделать из асинхронного режима запросов синхронный, для чего пускал qttp в отдельном потоке - так и не удалось победить - вешается зараза в WaitForMultipleObjects
QByteArray loader()
{
QHttp http;
http.setHost( ... );
http.get( ... );
while( http.state() != QHttp::Closing )
QApplication::processEvents();
return http.readAll();
}
Для того, что бы сделать работу QHttp синхронной, нужно что бы отрабатывали QSocketNotifier. Для этого нужно крутить eventloop (именно там происходят необходимые действия). Предыдущий пример показывал саму идею, "боевой" код я бы сделал примерно таким:
QByteArray loader()
{
QHttp http;
QEventLoop loop;
QObject::connect( &http, SIGNAL( done( bool ) ), &loop, SLOT( quit() ) );
http.setHost( ... );
http.get( ... );
loop.exec();
// выходим из цикла при получении сигнала QHttp::done
// Проверили ошибки....
qDebug() << http.state() << http.error() << http.bytesAvailable();
return http.readAll();
}
BRE, то, что вы предлагаете - очень опасная практика. Начнут прокачиваться сообщения, т.е. вызываться слоты\обработчики, которые в данный момент времени (посреди работы функции) вызываться совершенно не должны.
Именно поэтому и создается отдельный поток, в который засовывается(moveToThread) объект QNetworkAccessManager там для него и идет прокачка сообщений, а вызывающий поток ждет.
Вчерашняя проблема решилась заменой QHttp на QNetworkAccessManager:)
void Thread::run()
{
QNetworkAccessManager manager;
connect( &manager, SIGNAL( finished(QNetworkReply*) ), SLOT( replyFinished(QNetworkReply*) ) );
manager.get( QNetworkRequest( QUrl("http://qtsoftware.com") ) );
exec();
}
void Thread::run()
{
QEventLoop loop;
QNetworkAccessManager manager;
connect( &manager, SIGNAL( finished(QNetworkReply*) ), &loop, SLOT( quit() ) );
manager.get( QNetworkRequest( QUrl("http://qtsoftware.com") ) );
loop.exec();
}
Ну смотри, допустим в очереди лежит два сообщения - на вызов Class1::slot1 и Class1::slot2. Вызывается slot1() - объект переходит в несогласованное состояние. Начинаем прокачку сообщений - сразу вызыватеся slot2, т.е. колл-стек такой:
----------------
slot2()
...
slot1()
...
-----------------
Поскольку объект в несогласованном состоянии (выполнение slot1 еще не закончилось) - ахтунг!
void Thread::run()
{
QNetworkAccessManager manager;
connect( &manager, SIGNAL( finished(QNetworkReply*) ), SLOT( replyFinished(QNetworkReply*) ) );
manager.get( QNetworkRequest( QUrl("http://qtsoftware.com") ) );
exec();
}
void Thread::run()
{
QEventLoop loop;
QNetworkAccessManager manager;
connect( &manager, SIGNAL( finished(QNetworkReply*) ), &loop, SLOT( quit() ) );
manager.get( QNetworkRequest( QUrl("http://qtsoftware.com") ) );
loop.exec();
// обработка ответа...
}
Давай отвлечемся от QNetworkAccessNanager - он тут совершенно не при чем сейчас
Смотри, есть два потока, в первом крутится obj1, во втором obj2:
Thr1 | Thr2
------ ------
Obj1 | Obj2
Первый поток эмитит два сигнала sig1, sig2 объекту, который находится во втором потоке.
Obj1 ->sig1->Obj2
Obj1 ->sig2->Obj2
Соответствующие слоты(slot1, slot2) не вызываются напрямую, а в очередь Thr2 кладутся сообщения для вызова этих слотов.
Дальше, Thr2 извлекает очередное сообщение, видит что это вызов слота slot1 - и вызывает его. Объект Obj2 переходит в несогласованное состояние. Внутри слота slot1 мы начинаем прокачивать сообщения (loop.exec()), Thr2 извлекает следующие сообщение из очереди - видит что это вызов слота slot2 и дергает его - опа приехали, еще не выйдя из slot1 уже запустили slot2!
Callstack:
----------
slot2()
.....
slot1()
....
------------
Естественно, вместо вызова слотов могут быть любые обработчики.
Для того чтобы решить эту проблему - и создается дополнительный поток - Thr3. В него помещается объект и сообщения этот объект получает в нем. А вызывающие поток ждет окончания Thr3 НЕ прокачивая при этом свои сообщения.
Тебе не кажется, что это немного надуманный пример.
Я привел тебе код, который будет работать в потоке синхронно.
Если существует возможность такой ситуации, о которой пишешь ты, то такие случаи нужно учитывать отдельно (например использовать Qt::BlockingQueuedConnection), а лучше так никогда не делать.
А прокрутка очереди сообщений, это вовсе не опасная практика. Она повсеместно используется в Qt: от оживления длительных операций и до модальных диалогов. Главное думать, что делаешь.
Надуманный?
Это крайне упрощенный пример.
Мне сложно представить многопоточное приложение, использующие очереди, в котором несанкционированная прокачка сообщений не будет проблемой. На эти грабли наступали уже не раз.
Приложение, над которым сейчас работаем активно использует пул потоков, пересылку сообщений между ними и минимум синхронизаций. Использование прокачки сообщений в коде - запрещено.
Кстати модальные диалоги - тоже не айс, именно по этой причине.
Я не говорю, что это должна быть запрещенная практика, просто многие люди не задумываются, что реально происходит при таком подходе. И каждое использование прокачки сообщений должно быть обдумано несколько раз, со всеми возможными последствиями.
Форум Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)