Solved

multithreaded programming or alternatively asynchronous HTTP request

Posted on 2006-11-20
10
1,142 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
 
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
Free Trending Threat Insights Every Day

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

 
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

Easy Project Management (No User Manual Required)

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

I imagine that there are some, like me, who require a way of getting currency exchange rates for implementation in web project from time to time, so I thought I would share a solution that I have developed for this purpose. It turns out that Yaho…
This article discusses how to create an extensible mechanism for linked drop downs.
Explain concepts important to validation of email addresses with regular expressions. Applies to most languages/tools that uses regular expressions. Consider email address RFCs: Look at HTML5 form input element (with type=email) regex pattern: T…
The viewer will learn how to dynamically set the form action using jQuery.

760 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

Need Help in Real-Time?

Connect with top rated Experts

20 Experts available now in Live!

Get 1:1 Help Now