. * * AunoAsyncHttp, a PHP class for handling multiple http requests * asynchronously in non-blocking manner with PHP. * * Sample usage of AunoAsyncHttpMulti: * * $http = new AunoAsyncHttpMulti; * $http->get("http://www.funcom.com/", $ob=NULL, "http_cb", "r1"); * $http->get("http://auno.org/", $ob=NULL, "http_cb", "r2"); * for(;;) * { * $fdr = $http->fdr; * $fdw = $http->fdw; * if(sizeof($fdr) + sizeof($fdw) == 0) * { * break; * } * if(socket_select($fdr, $fdw, $fde=NULL, 10)) * { * $http->iteration($fdr, $fdw); * } * } * function http_cb($body, $head, $args) * { * echo "Completed HTTP request $args\n"; * var_dump($head); * var_dump($body); * } * ************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * */ class AunoAsyncHttp { var $dfunc, $dargs; var $url, $host, $port, $page; var $socket, $active, $state, $data; function AunoAsyncHttp(&$ob, $method, $args=NULL) { if($ob === NULL) $this->dfunc = $method; else $this->dfunc = array(&$ob, $method); $this->dargs = $args; $this->state = 0; $this->active = 0; } function get($url) { if(preg_match('#^http://([-.0-9a-z]+)(:[0-9]+)?(/.*)?#i', $url, $reg) == 0) { echo "Invalid url to get()\n"; return NULL; } $this->host = $reg[1]; $this->port = empty($reg[2]) ? 80 : (int)$reg[2]; $this->page = empty($reg[3]) ? '/' : $reg[3]; $res = $this->socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); $res = socket_set_nonblock($this->socket); $res = @socket_connect($this->socket, $this->host, $this->port); $res = socket_last_error($this->socket); if(socket_last_error($this->socket) !== SOCKET_EINPROGRESS) { socket_close($this->socket); return NULL; } $this->state = 1; $this->active = time(); return $this->socket; } function iteration() { if($this->state == 1) { $this->active = time(); socket_write($this->socket, "GET ".$this->page." HTTP/1.0\r\n"); socket_write($this->socket, "Host: ".$this->host."\r\n"); socket_write($this->socket, 'User-Agent: AunoAsyncHttp/$Revision: 1.3 $'."\r\n"); socket_write($this->socket, "Connection: close\r\n"); socket_write($this->socket, "\r\n"); $this->state = 2; } else if($this->state == 2) { $this->active = time(); $data = socket_read($this->socket, 0xffff); if(empty($data)) return $this->finish(); else $this->data .= $data; } else { return false; } return true; } function finish() { socket_close($this->socket); $this->state = 3; $this->active = 0; list($head, $body) = split("\r?\n\r?\n", $this->data, 2); call_user_func($this->dfunc, $body, $head, $this->dargs); return false; } } class AunoAsyncHttpMulti { var $httpmap, $fdr, $fdw; function AunoAsyncHttpMulti() { $this->httpmap = array(); $this->fdr = array(); $this->fdw = array(); } function get($url, &$ob, $method, $args=NULL) { $http = new AunoAsyncHttp(&$ob, $method, $args); $sock = $http->get($url); if($sock !== NULL) { $this->httpmap[$sock] = $http; $this->fdw[] = $sock; } } function iteration($fdr, $fdw) { if(sizeof($fdr)) { $arr = array(); foreach($fdr as $sock) if(isset($this->httpmap[$sock])) if($this->httpmap[$sock]->iteration() == false) { $arr[] = $sock; unset($this->httpmap[$sock]); } if(sizeof($arr)) $this->fdr = array_diff($this->fdr, $arr); } if(sizeof($fdw)) { $arr = array(); foreach($fdw as $sock) if(isset($this->httpmap[$sock])) { $arr[] = $sock; if($this->httpmap[$sock]->iteration() == true) $this->fdr[] = $sock; } if(sizeof($arr)) $this->fdw = array_diff($this->fdw, $arr); } } } ?>