Solved

multithreaded programming or alternatively asynchronous HTTP request

Posted on 2006-11-20
10
1,144 Views
Last Modified: 2008-01-09
Hi,

I'm working on a website, which sends two HTTP requests to other servers. The data sent is logging data, so I don't need to process the HTTP response necessarily.

Is it possible to create a seperate thread in PHP for those HTTP requests?

Or is it possible to send the HTTP requests asynchronously?

As already mentioned, its not necessary to process the HTTP response, but it would be nice if it was possible.

Thanks a lot!
0
Comment
Question by:TheFunkSoulBrother
10 Comments
 
LVL 35

Expert Comment

by:Raynard7
ID: 17978070
Unfortunatley PHP does not directly support threading.

You could send the HTTP requests asynchronously by using the process given at
http:Q_21142767.html "PHP Thread?"

where you make one request - then use fread() to grab the details from the request, whilst you are waiting for the fread to operate you can then make your second requrest
0
 
LVL 48

Expert Comment

by:hernst42
ID: 17979942
With curl you can process multiple HTTP-requests at the same time. See http://de3.php.net/manual/en/function.curl-multi-exec.php And curl ist also cappavble of getting the response code from the server.
0
 
LVL 1

Author Comment

by:TheFunkSoulBrother
ID: 17985745
Thanks for the links.

How do I call a script several times (like suggested in http:Q_21142767.html)?
I've got my code in index.php and I want to call e.g. sendHTTPrequest_001.php and sendHTTPrequest_002.php simultaneously - is that possible, or did I get something wrong?
0
Comprehensive Backup Solutions for Microsoft

Acronis protects the complete Microsoft technology stack: Windows Server, Windows PC, laptop and Surface data; Microsoft business applications; Microsoft Hyper-V; Azure VMs; Microsoft Windows Server 2016; Microsoft Exchange 2016 and SQL Server 2016.

 
LVL 48

Accepted Solution

by:
hernst42 earned 200 total points
ID: 17985789
If each of the sendHTTPrequest_x.php perform its own request,

From http://de3.php.net/manual/en/function.curl-multi-exec.php

<?php
$mh = curl_multi_init();

for ($i=1; $i<=2; ++$i) {
  $conn[$i] = curl_init('http://yourservername/sendHTTPrequest_00' .$i . '.php');
  curl_setopt($conn[$i], CURLOPT_RETURNTRANSFER, 1);
  curl_multi_add_handle ($mh,$conn[$i]);
}

// start performing the request
do {
  $mrc = curl_multi_exec($mh, $active);
} while ($mrc == CURLM_CALL_MULTI_PERFORM);

while ($active and $mrc == CURLM_OK) {
  // wait for network
  if (curl_multi_select($mh) != -1) {
   // pull in any new data, or at least handle timeouts
   do {
     $mrc = curl_multi_exec($mh, $active);
   } while ($mrc == CURLM_CALL_MULTI_PERFORM);
  }
}

if ($mrc != CURLM_OK) {
  print "Curl multi read error $mrc\n";
}

// retrieve data
for ($i=1; $i<=2; ++$i) {
  if (($err = curl_error($conn[$i])) == '') {
   $res[$i]=curl_multi_getcontent($conn[$i]);
  } else {
   print "Curl error on handle $i: $err\n";
  }
  curl_multi_remove_handle($mh,$conn[$i]);
  curl_close($conn[$i]);
}
curl_multi_close($mh);

print_r($res);
0
 
LVL 14

Expert Comment

by:Aamir Saeed
ID: 17987049
You could just send the request headers and move on.... fsockopen() would be used here, or cURL

proc_open() could be of interest too, but I wouldn't recommend it.
0
 
LVL 8

Assisted Solution

by:jk2001
jk2001 earned 50 total points
ID: 18000894
PHP doesn't do threads, but it does unix process control.

http://us3.php.net/manual/en/ref.pcntl.php

Factor your code into three distinct parts, and use pcntl_fork() to launch clones of yourself, and do the requests.

Personally, I would do something completely different, and a little easier on the server.  I'd write the requests to a queue (a db table) and have a daemon written in perl or c that reads the queue, and requests the URLs, in series.

If I knew how, I'd communicate directly with the daemon via a unix socket, but that's beyond me at this time.  The daemon would take requests and process them asynchronously.  That use the fewest resources.
0
 
LVL 1

Author Comment

by:TheFunkSoulBrother
ID: 18004432
First of all, thanks a lot for your suggestions.
Unfortunately I had no time to implement it an will not have until next week, but it seems to me that curl will work fine.

I think, it would be best to do the logging after a output buffer flush, so the webpage is displayed to the user while the logging runs in the background, right?

I'm developing the application on a Windows server, so i guess pcntl_fork() won't work.

Actually I like most the approach jk2001 suggested, maybe I'll implement it that way.
Did you mean with "communicate via unix socket" that a - for example - C deamon listens for connections (via SOCKET: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winsock/winsock/socket_2.asp) and PHP sends the logging data to the C deamon (using fsockopen() => http://at.php.net/sockets)
0
 
LVL 1

Author Comment

by:TheFunkSoulBrother
ID: 18069262
Thank you very much.
0
 
LVL 1

Author Comment

by:TheFunkSoulBrother
ID: 18084004
The approach with CURL multi seems a bit weird to me.
I couldn't find out how to execute code WHILE curl_multi_exec performs the two HTTP requests.
It seems to me that curl_multi_exec performs the HTTP requests at the same time but doesn't allow other code to be executed at the same time. Could that be?





I found another solution, which actually is very simple to implement and works like a charm.
This solution uses simply fsockopen as the requests are performed asynchronously by default.

$fp1 = fsockopen("http://www.url1.com", 80);
fputs($fp1, "POST http://www.url1.com HTTP/1.1\r\n");
...

$fp2 = fsockopen("http://www.url2.com", 80);
fputs($fp2, "POST http://www.url2.com HTTP/1.1\r\n");
...

echo "hello"; // some code which is executed while the two requests are performed
                   // looks like real multithreading!!!


// now get the response of the two HTTP requests
$buf1="";
while (!feof($fp1)) $buf1 .= fgets($fp1,128);
fclose($fp1);

$buf2="";
while (!feof($fp2)) $buf2 .= fgets($fp2,128);
fclose($fp2);
0
 
LVL 1

Author Comment

by:TheFunkSoulBrother
ID: 18084006
Sorry, the code for creating and sending the HTTP requests should be like this:

$fp1 = fsockopen("http://www.url1.com", 80);
fputs($fp1, "POST dosomething1.php HTTP/1.1\r\n");
...

$fp2 = fsockopen("http://www.url2.com", 80);
fputs($fp2, "POST dosomething2.php HTTP/1.1\r\n");
...
0

Featured Post

Master Your Team's Linux and Cloud Stack!

The average business loses $13.5M per year to ineffective training (per 1,000 employees). Keep ahead of the competition and combine in-person quality with online cost and flexibility by training with Linux Academy.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
PHP installation issues 11 60
php construct 5 26
insert into database through form with dynamic fields. 2 28
PHP Syntax Error 4 27
Author Note: Since this E-E article was originally written, years ago, formal testing has come into common use in the world of PHP.  PHPUnit (http://en.wikipedia.org/wiki/PHPUnit) and similar technologies have enjoyed wide adoption, making it possib…
Things That Drive Us Nuts Have you noticed the use of the reCaptcha feature at EE and other web sites?  It wants you to read and retype something that looks like this.Insanity!  It's not EE's fault - that's just the way reCaptcha works.  But it is …
The viewer will learn how to look for a specific file type in a local or remote server directory using PHP.
This tutorial will teach you the core code needed to finalize the addition of a watermark to your image. The viewer will use a small PHP class to learn and create a watermark.

770 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question