|
|
|
// 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;
|
|
}
|