I 'm writing a C++ client program quering a postgreSQL database via the internet. I want to handle the event when while waiting for an answer, a network connection problem occurs and so the client can't receive any messages from the database server. But when I manually turn off the internet connection the program remains idle even if I turn the connection on again later. Is there a way to catch this event or at least set a timeout on client-side so that it stops waiting for an answer after it?
After searching around following private data public channel 2 suggestion to use socket operations I've reached to the following solution:
pqxx::connection conn("host=blabla.com "
"port=5432 "
"user=abla "
"password=abla "
"dbname=ablabla");
const int val1 = 1;
if ( setsockopt(conn.sock(), SOL_SOCKET, SO_KEEPALIVE, &val1, sizeof(val1)) < 0){
perror( "setsockopt failed\n");
}
const int val2 = 5;
if ( setsockopt(conn.sock(), IPPROTO_TCP, TCP_KEEPCNT, &val2, sizeof(val2)) < 0){
perror( "setsockopt failed\n");
}
const int val3 = 2;
if ( setsockopt(conn.sock(), IPPROTO_TCP, TCP_KEEPINTVL, &val3, sizeof(val3)) < 0){
perror( "setsockopt failed\n");
}
const int val4 = 10;
if ( setsockopt(conn.sock(), IPPROTO_TCP, TCP_KEEPIDLE, &val4, sizeof(val4)) < 0){
perror( "setsockopt failed\n");
}
TransactorImpl transac();
conn.perform(transac,10);
This way 10 seconds after I disconnect from the network the socket starts sending probes to ensure the connection is OK and after a while it aborts the connection and my overriden on_abort()
function is called and after that libpqxx retries to execute the query. The number of retries is specified by the second argument of the perform()
function (in this case 10).