POCO HTTPServerRespone async problem

Hi everybody,

I am trying to implement a simple REST API server in oF.
I started out with a simple implementation of the POCO webserver implementation.

It all works fine but I don’t see how I can handle async calls before a response from my server…

This is some pseudo code of what I have:

void NCHandlePrepareCameraWithPreset::handleRequest(Poco::Net::HTTPServerRequest& request, Poco::Net::HTTPServerResponse& response) {

         response.setContentType("application/json");
         //openframeworks do some stuff and wait for an event
         someotherClass.doSomething();
         ofAddListener(someotherClass::DONE, this, &done);        
         //do not send the response
         //response.send() }

 void NCHandlePrepareCameraWithPreset::done(){
     //should do response.send() here
     //but how do I get a reference to response here??
}

My question is what if my program has to wait for an incoming event from somewhere else before it can do the response.send().
I have tried to set some pointers to the reference of HTTPServerResponse but that doesn’t seem to work.

Thank you so much for your help,

Hey there – I’m not exactly sure what you’re trying to do – but I do know that Poco’s server system uses a factory model with a thread for each handler, thus you’re going to have to synchronize multiple threads using a mutex – or perhaps better a Poco::Condition (http://pocoproject.org/slides/130-Threads.pdf).

Also if you are looking for other reference for how to build servers using Poco, I’ve got quite an extensive system set up in ofxHTTP and ofxJSONRPC for triggering events via the browser, etc.

The https://github.com/bakercp/ofxHTTP/tree/master/example_basic_ip_video_server example shows one way how to synchronize data across connections.

Hi Baker,

Thank you so much for responding.
I just need a simple basic http server that can handle GET/PUT/POST requests in JSON and send JSON back.

The ofxHTTP library, including the ip video server, is a fantastic help but it is very complex and to be honest I do not find my way around in it. It has nothing to do with the use of shared pointers though.

I have attached a simple project to show you what I mean.
src.zip (6.6 KB)

Let’s say I have a client doing a GET call to our server.
http://localhost/api/dosomething

Now I have this class with a requesthandler that is generated from another class that inherits from HTTPRequestHandlerFactory.

Now when the call from the client enters the handleRequest method from our handlerClass, it get’s disposed out of memory right away when the call is finished.

Now what I want is that in our handleRequest method waits for another process to be finished before disposing our class entirely and then send the response back to the client.

Now is it every time the factory returns a new handlerClass, that this class runs in it’s own thread? I am not very sure what is going on and what to do to stop the thread or even how to access it.

I hope my example makes it a bit clearer?

I know the answer is probably somewhere in your basic ip video server but I can’t seem to get through it… :flushed:

Thank you very much in advance for your help.

So, to clarify I think you are adding another thread when you don’t need to …

void NCGETHandleRootRequest::handleRequest(Poco::Net::HTTPServerRequest& request, Poco::Net::HTTPServerResponse& response) {

	Poco::URI uri(request.getURI());
	response.setContentType("application/json");
	//INSERT PROMISES HERE?
	dosomething.doSomething();
	//when dosomethingisdone proceed here
	/*
	std::string test = "{\"Message\":\"You just called nothing. The people get what the people want...\"}";
	std::ostream& ostr = response.send();
	ostr<<test;
	ostr.flush();*/
}

When (and if) this method completes, the thread that was assigned to run it will be be disposed. The problem seems to be that you are spawning another thread from that thread that the HTTP factory gave you …

Is there any reason you couldn’t do all of your work in that function above, rather than spawning another thread altogether?

First of all, thank you for looking into this.

Let me try to explain what I am trying to do. I am trying to control a moving head camera with a rest API.
Pure tcp sockets would be a better approach I guess, but I can not use that for this project.

So the clients sends a GET call to the server.
Something like this:
GET http://localhost:1715/movecamerato/xpos/ypos

The server receives this call, get the parameters from the URI and then sends a command to the camera to start moving to the desired x and y coordinates. When the camera reaches it’s position (this can take up to 2 seconds) then the server should send a response back to the client.

The problem is that this camera does not have a callback to tell me when it’s final position has been reached.
My workaround for this is that when our server tells the camera to start moving, I poll every 120ms for it’s new position (that we can do) I use an ofxtimer util class to do this. Then every 120ms I check if the current position matches the desired position. When the desired position has been reached I stop the timer and throw an ofNotifyEvent.

I don’t see a way to do all this within the handleRequest method. It would be awesome if I could find a way to interupt the thread created by the factory, do all of my stuff with the camera, catch the event, resume the thread and send a response back to the client.

Maybe it has something to do with this?
http://pocoproject.org/forum/viewtopic.php?f=10&t=3470&p=5531&hilit=HTTPRequestHandler#p5531

Right now, I am a bit in the dark :wink:

This is an example of the app (without the http server, just moving the camera, in this case with face detection but that is not of importance regarding to the rest API)

wimvanhenden,

My name is (Mr) Tish Wood. I have been watching this thread and think I may have some ideas…and I need to the same/similar code you do for a project I am working on…though I think the problem/product domain you are trying to satisfy it totally different.

At the point you are experiencing problems is very similar to Java’s implementation of the HTTP protocol…and I have used it a great deal. After looking at Mr Baker’s discussion, what I think should be happening is that in your:

Poco::Net::HTTPRequestHandler* NCRequestHandlerFactory::createRequestHandler(const Poco::Net::HTTPServerRequest &request)

you should be calling your:

void NCGETHandleRootRequest::handleRequest(Poco::Net::HTTPServerRequest& request, Poco::Net::HTTPServerResponse& response).

However, I believe you need to instantiate Poco::Net::HTTPServerResponse to pass to NCGETHandleRootReques(…). Unfortunately, Poco::Net::HTTPServerResponse is an Abstract class…so I don’t think it can be instantiated.

If you or someone else can direct me to an implementation of the HTTPServerResponse, I’ll see if I can get this working and pass you back the fix. I am spinning my wheels looking for a usable HTTPServerResponse. If there isn’t one, then that information would provide me some direction as to what my next step is.

Hope to hear from you soon…

Hi Tish,

I am sorry for my late reply. This project involves a lot of other things that needed some attention.
The thing is, that I have still not found a solution to this. To be very honest I haven’t researched it in depth to solve it.

To overcome this problem I have used a different architecture on the client side using callbacks.
The client now has to act as a server as well.

Whenever a client makes a call to the server it now has to pass a callback url. Whenever my action is complete my server acts as a client a makes a call to this callback url.

For example:

  1. The client makes a call to my server like this:
    http://10.32.456.27:1715/something/A/B/C?callbackurl=http://10.34.444.32:837474/D/F/V

2.The server catches this and does some magic with moving cameras around. This can take up to a few seconds.
So in the handleRequest I create a pointer to a class that keeps listening for the events when the cameras are in place:

void NCHandlePreapreCameraWithPreset::handleRequest(Poco::Net::HTTPServerRequest& request, Poco::Net::HTTPServerResponse& response) {
	response.setContentType("application/json");
	response.setKeepAlive(true);
         //get all the stuff you need from the clients request
         //id, temppresetid, callbackurl and so on.
    
        NCCallBackManager *manager = new NCCallBackManager();
        manager->startListeningForCamPanTiltZoom(id, temppresetid,_callbackurl, manager->REGULAR_PRESET);

	response.send();
}

Notice that the class NCCallBackManager is not deleted here.
It deletes itself once it’s works is done. That is definitely not the best way to handle this, but for now it works…

3.When this CallBackManager class receives the incoming event that the cameras are done it acts as a client and use the callbackurl to notify the client/server on the other side that the work is done.

Poco::URI uri(thisisthecallbackurl);
Poco::Net::HTTPClientSession client_session(uri.getHost(), uri.getPort());
//Prepare and send request
string path(uri.getPathAndQuery());
Poco::Net::HTTPRequest req(Poco::Net::HTTPRequest::HTTP_GET, path, Poco::Net::HTTPMessage::HTTP_1_1);
client_session.sendRequest(req);

Now this implementation is a serious detour just to make things work.

I still haven’t figured out how to make HTTPServerResponse wait for other tasks without being destroyed first. I have to admit I am not very skilled in threading and going deep into the core Poco threading/server stuff…

I hope you may have found an answer to this or have found at least a road that is pointing in the right direction :wink:

Thanks.