Persistent/Keepalive Http With the PHP Curl Library

Persistent/keepalive HTTP with the PHP Curl library?

cURL PHP documentation (curl_setopt) says:

CURLOPT_FORBID_REUSE - TRUE to force
the connection to explicitly close
when it has finished processing, and
not be pooled for reuse.

So:

  1. Yes, actually it should re-use connections by default, as long as you re-use the cURL handle.
  2. by default, cURL handles persistent connections by itself; should you need some special headers, check CURLOPT_HTTPHEADER
  3. the server may send a keep-alive timeout (with default Apache install, it is 15 seconds or 100 requests, whichever comes first) - but cURL will just open another connection when that happens.

Php curl keep alive connection

Sending multiple messages, and using keep-alive are two separate things. With Nexmo (as the FAQ mentions) you can only send a single SMS per HTTP request. To send multiple SMS, you just have to make multiple HTTP requests.

By default, Nexmo will allow your account to make 5 requests per second to the SMS API. If you want to maximize your throughput, you need to make sure you're making the request as fast as possible (or really, just at least as fast at that 5/second rate limit).

That's where the keep-alive comes into play, making sure you're sending the requests as fast as possible. The curl_setop docs reference a CURLOPT_FORBID_REUSE which allows:

TRUE to force the connection to explicitly close when it has finished processing, and not be pooled for reuse.

So by default, curl is trying to use keep-alive, assuming you reuse the curl handle. See this question for more details on that.

Borrowing this code from the quickstarts here (disclosure, I'm the author of those):

<?php
$url = 'https://rest.nexmo.com/sms/json?' . http_build_query([
'api_key' => API_KEY,
'api_secret' => API_SECRET,
'to' => YOUR_NUMBER,
'from' => NEXMO_NUMBER,
'text' => 'Hello from Nexmo'
]);

$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);

If you use curl_setop() to set a new CURLOPT_URL with a different number / message (which reuses the curl handle) curl should be using keep-alive by default.

But keep in mind, this doesn't change how you send multiple messages with Nexmo, it's just a way to optimize the speed at which you send the messages.

Setting --keepalive-time for curl in php

If you are using PHP 5.5 or greater (currently 5.5, 5.6, & 7) built with cURL 7.25.0 or greater, you can set these cURL options in PHP to match the --keepalive-time parameter (PHP <= 5.4 did not have these cURL options available):

curl_setopt($session, CURLOPT_TCP_KEEPALIVE, 1);
curl_setopt($session, CURLOPT_TCP_KEEPIDLE, 30);
curl_setopt($session, CURLOPT_TCP_KEEPINTVL, 15);

The CURLOPT_TCP_KEEPIDLE constant in libcurl corresponds to the --keepalive-time command line option for curl.

See the cURL docs regarding CURLOPT_TCP_KEEPALIVE, CURLOPT_TCP_KEEPIDLE, and CURLOPT_TCP_KEEPINTVL for more info.

Note: These options are not available and can't be used if you have PHP 5.4 or lower.

Persistent connection with libcurl

Yes, that's entirely correct. Keep re-using the same easy handle and libcurl will try to re-use connections as much as possible.

stream_get_contents gets stuck on persistent (KeepAlive) connection


$opts = array('http' =>
array(
'method' => 'GET',
'protocol_version' => 1.1,
'header' => 'Connection: close'
)
);

Connection: close tells the server not to use a persistent connection and to drop the TCP connection after the response has been sent.

This is part of the HTTP/1.1 standard, and as the PHP manual says:

If [protocol_version] is set to 1.1 it is your responsibility to be 1.1 compliant.

PHP: Keep HTTPS Connection to API open throughout multiple requests

I ended up making these requests through the browser.
Browsers keep HTTP(S) connections open when the server tells them to.

Alas, this solution entails some disadvantages:

  • authentication is more difficult
  • more load on the server as more connections have to be maintained
  • the solution needs additional JavaScript

But requests are much faster (about 3x) and load on the server where WordPress is running is minimized.

php and persistent HTTP connections

The pecl_http extension for PHP uses libcurl and allows you to open a persistent TCP connection that can be reused:

$client = new http\Client('curl', $persistentHandleID); 
$request = new http\Client\Request('GET', 'http://example.com/');
$client->enqueue($request);
$client->send();
$response = $client->getResponse($request);

If another $client running on the same PHP process (possibly during a different PHP request) accesses the same host and shares the same $persistentHandleID, it will send its HTTP requests over the same TCP connection as before.

The TCP connection will be kept alive until the PHP module is shut down or until the $client sends Connection: Close or forbids further use of the connection:

$client->setOptions(['forbid_reuse' => true, … ]);


Related Topics



Leave a reply



Submit