the doubt have correct design of software implements multiple , nested get/post request.
say have run login() function requires , post , retrievexyz() requires 2 gets (and on, scalable).
the way thinkig like
mainwindow.cpp //code login(); retrievexyz(); //code mainwindow::login(){ //code connect(nam, signal(finished()), this, slot(ongetloginfinished())); nam->get(...); } mainwindow::ongetloginfinished(){ //do stuff connect(nam, signal(finished()), this, slot(onpostloginfinished())); nam->post(...); } mainwindow::onpostloginfinished(){ //do stuff } mainwindow::retrievexyz(){ //code connect(nam, signal(finished()), this, slot(onget1retrievefinished())); nam->get(); //code } mainwindow::onget1retrievexyzfinished(){ //do stuff connect(nam, signal(finished()), this, slot(onget2retrievefinished())); nam->get(); }
or should use qsignalmapper ? correct/efficient way so? i've seen people using sender() cast didn't understand point.
basically retrieve particular reply finished() signal rather general 1 (or of qnam)
this method may work not nice , clean me
is best can get?
moving connect approach reply?
i got like:
struct requestresult { int httpcode; qbytearray content; }; requestresult executerequest(const std::function<qnetworkreply*(qnetworkaccessmanager&)>& action, const std::chrono::milliseconds& timeout) { qeventloop eloop; qtimer timeouttimer; qnetworkaccessmanager nam; qobject::connect(&timeouttimer, &qtimer::timeout, &eloop, &qeventloop::quit); qobject::connect(&nam, &qnetworkaccessmanager::finished, &eloop, &qeventloop::quit); timeouttimer.setsingleshot(true); timeouttimer.setinterval(timeout.count()); timeouttimer.start(); auto resettimeout = [&timeouttimer]() { timeouttimer.start(); }; qnetworkreply* reply = action(nam); qobject::connect(reply, &qnetworkreply::uploadprogress, resettimeout); qobject::connect(reply, &qnetworkreply::downloadprogress, resettimeout); eloop.exec(); if (!timeouttimer.isactive()) { throw std::runtime_error("time out"); // custom exception } const int httpstatus = reply->attribute(qnetworkrequest::attribute::httpstatuscodeattribute).toint(); auto content = takecontent(*reply); // reply->readall , decompression return requestresult{httpstatus, content}; }
and functions get/delete/post/.. similar to
auto requestget(const qnetworkrequest& request) { return executerequest([&](qnetworkaccessmanager& nam) { return nam.get(request); }, timeout); } auto requestdelete(const qnetworkrequest& request) { return executerequest([&](qnetworkaccessmanager& nam) { return nam.deleteresource(request); }, timeout); } auto requestpost(const qnetworkrequest& request, qhttpmultipart& multipart) { return executerequest([&](qnetworkaccessmanager& nam) { return nam.post(request, &multipart); }, timeout); }
then, code, like
mainwindow::login() { const auto getres = requestget(..); // ... const auto postres = requestpost(..); // ... }
and may use thread , future if want not blocking calls.
Comments
Post a Comment