webServer and wxThread, multi threading? Topic is solved

If you are using the main C++ distribution of wxWidgets, Feel free to ask any question related to wxWidgets development here. This means questions regarding to C++ and wxWidgets, not compile problems.
Post Reply
Natulux
Filthy Rich wx Solver
Filthy Rich wx Solver
Posts: 242
Joined: Thu Aug 03, 2017 12:20 pm

webServer and wxThread, multi threading?

Post by Natulux »

Hey guys,

I want to add a https webserver to my main application, running in a local network, no need to access or receive from other networks.
It should be able to receive and provide simple text data, as well as binary data (movies or pictures) and is probably accessed from multiple clients at any given time.

This webserver is created with the sample code from "eidheims Simple Web Server" on GitHub. I stripped it of its boost parts, using only ASIO standalone, and included it in the wxWidgets 3.1.0 minimal sample.

The Webserver class derives from wxThread

Code: Select all

class WebServer :	public wxThread
and is called in the initialisation of the main loop

Code: Select all

WebServer *webServer = new WebServer();
if (webServer->Create() == wxTHREAD_NO_ERROR) 
{
	if (webServer->Run() != wxTHREAD_NO_ERROR)
	{
		wxMessageBox("Fehler beim starten des Webserver-Threads!");
	}
}
The webserver is up and running and is able to receive and answer requests, while the main application is allowed to run in the main thread.
But now Im wondering how to exchange data between the threads "thread safe". After the webserver got a POST I want to react to this data with the main application (other thread) and send a response accordingly:

Code: Select all

	m_webserver.resource["^/fullJson$"]["POST"] = [this](shared_ptr<HttpsServer::Response> response, shared_ptr<HttpsServer::Request> request) 
	{
		wxString sRet = UsePostedData(sBuff);
		*response << "HTTP/1.1 200 OK\r\n"
				<< "Content-Length: " << sRet.length() << "\r\n\r\n"
				<< sRet;
	}
	catch (const exception &e) 
	{
		stringstream ssRet;
		ssRet << "HTTP/1.1 400 Bad Request\r\nContent-Length: " << strlen(e.what()) << "\r\n\r\n" << e.what();
		response->write(ssRet);
	};
In my example above, "UsePostedData(sBuff);" should somehow pass on the data. But while the data is beeing used, the server is waiting until ready to respond and is not reacting to requests anymore which is of course not acceptable. (I tested this by calling a wxMessageBox).
I thought about adding the data to a dynamic array, which I query and clean with a timer from the main thread. But how then should I respond to the query if the webserver already finished the request (asynchron).

I fear Im lacking the understanding of how multi threading is supposed to work, at least in combination with a webserver.

Some clarity, anyone? Thank you! :-)
Have a great one
Natu
User avatar
T-Rex
Moderator
Moderator
Posts: 1248
Joined: Sat Oct 23, 2004 9:58 am
Location: Zaporizhzhya, Ukraine
Contact:

Re: webServer and wxThread, multi threading?

Post by T-Rex »

When you want to handle the POST data, create another thread (I personally think that std::thread could be easier for you) and pass the lambda function there which grabs the outer data by reference. But indeed, you will need to store the POST data somewhere to ensure that it stays alive after your callback function finishes.
http://www.bogotobogo.com/cplusplus/C11 ... ctions.php
Natulux
Filthy Rich wx Solver
Filthy Rich wx Solver
Posts: 242
Joined: Thu Aug 03, 2017 12:20 pm

Re: webServer and wxThread, multi threading?

Post by Natulux »

Thank you for your quick answer.
After scamming thorugh the original sample code again, I found what you are telling me, which I didn't quite get back when I took parts of that code:

Code: Select all

  server.resource["^/work$"]["GET"] = [](shared_ptr<HttpsServer::Response> response, shared_ptr<HttpsServer::Request> /*request*/) {
    thread work_thread([response] {
      this_thread::sleep_for(chrono::seconds(5));
      response->write("Work done");
    });
    work_thread.detach();
  };
Head -> Table.
Quite obvious actually.

I tried it and it works fine.
Thank you. :-)
Greets
Natu
Post Reply