Project

General

Profile

RE: Using HttpClient from inside a WApplication ยป main.cpp

Stefan Lanz, 01/08/2015 02:53 PM

 

// STDLIB
#include <memory>
#include <iostream>
#include <algorithm>
#include <exception>
#include <thread>
#include <chrono>
#include <ctime>

// WT
#include <Wt/WApplication>
#include <Wt/WServer>
#include <Wt/WContainerWidget>
#include <Wt/WPushButton>
#include <Wt/WTextArea>
#include <Wt/WBreak>

#include <Wt/WIOService>
#include <Wt/Http/Client>
#include <Wt/Http/Message>


// BOOST

// PROJECT

const char *CUSTOM_URL = "http://redmine.webtoolkit.eu";

void sleep(long long duration)
{
std::chrono::milliseconds ms(duration);
std::this_thread::sleep_for(ms);
}

class CustomRequest
{
public:
CustomRequest()
: m_apiClient(nullptr),
m_requestMessage(new Wt::Http::Message()),
m_responseMessage(nullptr),
m_responseHandled(false)
{
m_apiClient.done().connect(this, &CustomRequest::handleResponse);
/*
if(!m_apiClient.get(CUSTOM_URL))
throw std::runtime_error("CustomRequest::get() - failed");
*/
if(!m_apiClient.post(CUSTOM_URL, *m_requestMessage))
throw std::runtime_error("CustomRequest::post() - failed");

}

~CustomRequest(){}

std::unique_ptr<Wt::Http::Message> const &responseMessage() const {return m_responseMessage;}
bool responseHandled(){return m_responseHandled;}

private:
void handleResponse(boost::system::error_code errorCode, Wt::Http::Message message)
{
if(errorCode)
Wt::log("error") << errorCode.message();
else
{
m_responseMessage.reset(new Wt::Http::Message());
m_responseMessage->addBodyText(message.body());
}

m_responseHandled = true;
}

private:
Wt::Http::Client m_apiClient;
std::unique_ptr<Wt::Http::Message> m_requestMessage;
std::unique_ptr<Wt::Http::Message> m_responseMessage;
bool m_responseHandled;

};

class CustomWidget : public Wt::WContainerWidget
{
public:
CustomWidget(Wt::WContainerWidget *parent = nullptr)
: m_button(nullptr),
m_reuestThread()
{
initialise();
}

~CustomWidget()
{
if(m_reuestThread.joinable())
m_reuestThread.join();

}

void initialise()
{
this->setWidth(300);
m_button = new Wt::WPushButton("request", this);
m_button->clicked().connect(this, &CustomWidget::requestButtonClicked);
}

private:
void doRequestWork(Wt::WApplication *app)
{
CustomRequest request;

while(!request.responseHandled())
sleep(100);

auto &response = request.responseMessage();
if(response)
{
Wt::WApplication::UpdateLock lock(app);
new Wt::WBreak(this);
new Wt::WTextArea(response->body(), this);

app->triggerUpdate();
}
}

void requestButtonClicked()
{
if(m_reuestThread.joinable())
m_reuestThread.join();

auto app = Wt::WApplication::instance();
m_reuestThread = std::thread(&CustomWidget::doRequestWork, this, app);
}

private:
Wt::WPushButton *m_button;
std::thread m_reuestThread;
};


Wt::WApplication *createApplication(const Wt::WEnvironment& env)
{
Wt::WApplication *app = new Wt::WApplication(env);
app->enableUpdates();
app->root()->addWidget(new CustomWidget());

return app;
}

int main(int argc, char **argv)
{
try
{
Wt::WServer server(argv[0]);

server.setServerConfiguration(argc, argv, WTHTTP_CONFIGURATION);
server.addEntryPoint(Wt::Application, createApplication);

if(server.start())
{
Wt::WServer::waitForShutdown();
server.stop();
}
}
catch(Wt::WServer::Exception& e)
{
std::cerr << e.what() << std::endl;
}
catch(std::exception &e)
{
std::cerr << "exception: " << e.what() << std::endl;
}

return 0;
}
    (1-1/1)