PDA

View Full Version : Synchronous HTTP requests and QEventLoop



bssldr
15th October 2010, 22:00
First of all I'm trying perform synchronous HTTP requests. QNetworkAccessManager doesn't seem to offer support for it, so I'm trying to emulate this with a separate event loop.



QNetworkAccessManager NAManager;
QUrl url ("http://www.google.com");
QNetworkRequest request(url);
QNetworkReply *reply = NAManager.get(request);
QEventLoop eventLoop;
QObject::connect(reply, SIGNAL(finished()), &eventLoop, SLOT(quit()));
eventLoop.exec();
std::cout << "finished" << std::endl; //request finished here


Question: is there a nicer way to achieve this?

Another question: is it possible to create an event loop that allows you to manually post events to it?

wysota
15th October 2010, 22:17
Question: is there a nicer way to achieve this?
Apart from wrapping it all in a single call, no.


Another question: is it possible to create an event loop that allows you to manually post events to it?
You don't post events to event loops but rather to objects. QEventLoop is such an object too of course but I can't think of a use case where you'd want to post an event to an event loop object.

squidge
16th October 2010, 00:32
I can't think of a way thats nicer from what you want to do.

QNetworkAccessManager was designed to be asynchronous. Why anyone would want a synchronous version is a little odd to me, but to each there own.

ChrisW67
18th October 2010, 00:55
Here is an example that uses a synchronous request.

A system can issue requests to services X, Y, and Z over the network at user request. If this is the first time in a program run that an operation is requested then the system must first request a "login" (L) of the user with the service provider before completing the operation X, Y, or Z. L must complete entirely before operation X, Y, or Z is continued because a cookie returned by L must be available during X, Y, or Z. If the operation X, Y, or Z fails because the cookie has expired or been otherwise rejected by the service provider (perhaps they reboot a server) then the L process must be completed followed by a repeated X, Y, or Z.

The L process looks like a classic synchronous request. What is the cleanest wholly asynchronous way to achieve this?

wysota
18th October 2010, 01:03
What is the cleanest wholly asynchronous way to achieve this?
I'd say a state machine plus a signal emission upon detection of a failed request due to session timeout. It's nothing difficult but I agree there are situations when doing things synchronously simplifies matters greatly.

ChrisW67
18th October 2010, 01:14
Good Morning Wysota,

Do you ever sleep? :)

I've just stocked up on caffeine to explore the state machine machine approach to something like the the scenario above with few extra quirks. I've not used QStateMachine in anger so this should be an interesting morning.

wysota
18th October 2010, 08:40
Good Morning Wysota,
Good morning ;)


Do you ever sleep? :)
If I don't suffer from insomnia or don't have deadlines for the next day then in general - yes.


I've just stocked up on caffeine to explore the state machine machine approach to something like the the scenario above with few extra quirks. I've not used QStateMachine in anger so this should be an interesting morning.

By saying "state machine" I didn't exactly mean QStateMachine although of course it can be used here as well, it's just sometimes it's an overkill to use it when a simple enum variable holding the state would suffice :)

pcman11
29th March 2017, 22:49
After years, but maybe helpfull. It is possible and makes possible to have one function with RETURN data. You can call it like:


QByteaArray array = get_data( QUrl url );


so very nice

this works fine for me:



QByteArray gsm::data_request( QUrl url ){
QNetworkReply* reply;
QEventLoop connection_loop;
connect(networkManager, SIGNAL( finished( QNetworkReply* ) ), &connection_loop, SLOT( quit() ) );
networkRequest.setUrl( url );
qDebug() << "reaching url: " << url;
reply = networkManager->get( networkRequest );
connection_loop.exec();
qDebug() << "get -> " << url << ", done, size: " << reply->bytesAvailable();
reply->deleteLater();
return reply->readAll();
}


so, it looks like you overloaded signal.