Poco::HTTPClientSession manage disconnections

69 Views Asked by At

I have a Poco::HTTPClientSession running on a Windows PC. I send JSON requests and receive responses as expected. The device I communicate with is connected to my PC via a switch (tell you more about this later).

Here is a minimal code

// Setup connection
URI uri("http://192.168.2.100:80/app.php");
HTTPClientSession* httpClient = new HTTPClientSession(uri.getHost(), uri.getPort());
// Settings to manage disconnections
httpClient->setConnectTimeout(Timespan(0, 500 * 1000));
httpClient->setKeepAliveTimeout(Timespan(0, 500 * 1000));
httpClient->setKeepAlive(true);

// Create request object
HTTPRequest request = HTTPRequest(HTTPRequest::HTTP_GET, uri.getPathAndQuery(), HTTPMessage::HTTP_1_1);
request.set("User-Agent", "API ASDS00-v1.0");
request.setContentType("application/json");

// Send request
string messageToSend = generateMessage();
request.setContentLength(messageToSend.size());
httpClient->sendRequest(request) << messageToSend;

// Receive response
HTTPResponse res;
istream& responseStream = httpClient->receiveResponse(res);
if(res.getStatus() == HTTPResponse::HTTPStatus::HTTP_OK)
{
  istreambuf_iterator<char> eos;
  cout << "Received message: " << string(std::istreambuf_iterator<char>(responseStream), eos) << endl;
}
else
{
  cout << "Response error: status " << res.getStatus() << "; reason: " << res.getReason() << endl;
}

// Close connection
httpClient->reset();
delete httpClient;

I need to detect disconnections as soon as possible. As you can see, I've set up the keepAlive check, and added a connection timeout. The keepAlive somehow works, but not 100%.

sendRequest()

If I disconnect the cable, on the PC side or on the device side, before sending the request, sendRequest() exits after ~500ms (the timeout set for keepAlive), due to a keepAlive error. And that's ok for me.

receiveResponse()

If I disconnect the cable on the PC side before calling receiveResponse(), the function exits with ConnectionAbortedException, ConnectionResetException exceptions (didn't inspect which condition generates one or the other exception yet; I'm ok with getting any of those). And that's ok.

If I disconnect the cable on the device side before calling receiveResponse(), the function hangs there, and exits after several seconds with a TimeoutException exception. Looks like the delay is due to the socket timeout set (i.e. via HTTPClientSession::setTimeout).

How to detect a disconnection during receiveResponse() when the disconnection happens on the device side?

I can play with timeout using setTimeout(), but I don't really like this approach. I'm ok having a timeout, but to manage actual communication timeout (e.g. the system got busy and it takes it a long time to answer), not to manage a disconnection. Also, some requests take time (several seconds), some are almost immediate; fine tune all timeout for any given request is quite hard.

General question: any other/better approach to detect disconnections? I'm using Poco library functionalities, but I can use basic functionalities to control this, if needed (e.g. access the underlying SOCKET).

0

There are 0 best solutions below