Skip to content

Instantly share code, notes, and snippets.

@zhujun1980
Created June 30, 2014 03:57
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zhujun1980/ae0d077cd7c0f3c304a3 to your computer and use it in GitHub Desktop.
Save zhujun1980/ae0d077cd7c0f3c304a3 to your computer and use it in GitHub Desktop.
AsyncHandler
<?php
class async_http {
protected static $ahttp = NULL;
public static function in() {
if(self::$ahttp == NULL) {
self::$ahttp = new async_http();
}
return self::$ahttp;
}
protected $mh = NULL;
protected $active = 0;
protected $map = array();
private function __construct() {
$this->mh = curl_multi_init();
}
public function __destruct() {
curl_multi_close($this->mh);
}
public function add($asynchandler) {
curl_multi_add_handle($this->mh, $asynchandler->getHttp());
$this->map[(string)$asynchandler->getHttp()] = $asynchandler;
do {
$mrc = curl_multi_exec($this->mh, $this->active);
} while($mrc == CURLM_CALL_MULTI_PERFORM);
}
public function wait($ah = false) {
$fin = false;
do {
do {
$mrc = curl_multi_exec($this->mh, $this->active);
} while($mrc == CURLM_CALL_MULTI_PERFORM);
while ($done = curl_multi_info_read($this->mh)) {
$asynchandler = $this->map[(string)$done['handle']];
$asynchandler->RequestCompeleted($done['result']);
if((string)$asynchandler === $ah) {
$fin = true;
}
curl_multi_remove_handle($this->mh, $done['handle']);
}
if($fin)
break; //读完了当前能够读取的所有数据,包括想要的数据
if($this->active > 0) {
curl_multi_select($this->mh, 0.1);
}
} while($this->active > 0);
}
}
<?php
class AsyncHandler extends ArrayObject {
protected $_http = null;
//Callback functions
protected $onRecvResponse = NULL;
protected $recvCtx = NULL;
protected $onBusiness = NULL;
protected $busCtx = NULL;
protected $onAPIReturn = NULL;
protected $apiCtx = NULL;
protected $finished = false;
public function __construct($http) {
$this->_http = $http;
parent::__construct(array());
}
public function getHttp() {
return $this->_http->_curlInit;
}
public function setOnRecvResponse($cb, $ctx) {
$this->onRecvResponse = $cb;
$this->recvCtx = $ctx;
}
public function setOnBusiness($cb, $ctx) {
$this->onBusiness = $cb;
$this->busCtx = $ctx;
}
public function setOnAPIReturn($cb, $ctx) {
$this->onAPIReturn = $cb;
$this->apiCtx = $ctx;
}
public function getArrayCopy() {
if(!$this->finished) async_http::in()->wait((string)$this);
return parent::getArrayCopy();
}
public function count() {
if(!$this->finished) async_http::in()->wait((string)$this);
return parent::count();
}
public function serialize() {
if(!$this->finished) async_http::in()->wait((string)$this);
return parent::serialize();
}
public function offsetGet($index) {
if(!$this->finished) async_http::in()->wait((string)$this);
return parent::offsetGet($index);
}
public function offsetExists($index) {
if(!$this->finished) async_http::in()->wait((string)$this);
return parent::offsetExists($index);
}
public function offsetSet($index, $newval) {
if(!$this->finished) async_http::in()->wait((string)$this);
return parent::offsetSet($index, $newval);
}
public function offsetUnset($index) {
if(!$this->finished) async_http::in()->wait((string)$this);
return parent::offsetUnset($index);
}
public function RequestCompeleted() {
$this->_http->processRequest();
$data = curl_multi_getcontent($this->getHttp());
if(is_callable($this->onRecvResponse)) {
$data = call_user_func($this->onRecvResponse, $this->_http, $data, $this->recvCtx);
}
if(is_callable($this->onBusiness)) {
$data = call_user_func($this->onBusiness, $data, $this->busCtx);
}
if(is_callable($this->onAPIReturn)) {
$data = call_user_func($this->onAPIReturn, $data, $this->apiCtx);
}
$this->exchangeArray($data);
$this->finished = true;
}
public function __toString() {
$id = __CLASS__ . (string)$this->getHttp();
return $id;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment