public function run(Promise &$promise)
 {
     $urlInfo = parse_url($this->url);
     $timeout = $this->timeout;
     if (!isset($urlInfo['port'])) {
         $urlInfo['port'] = 80;
     }
     $cli = new \swoole_http_client($urlInfo['host'], $urlInfo['port']);
     $cli->set(array('timeout' => $timeout, 'keepalive' => 0));
     $cli->on("error", function ($cli) use(&$promise) {
         Timer::del($cli->sock);
         $promise->accept(['http_data' => null, 'http_error' => 'Connect error']);
     });
     $cli->on("close", function ($cli) use(&$promise) {
     });
     $cli->execute($this->url, function ($cli) use(&$promise) {
         Timer::del($cli->sock);
         $cli->isDone = true;
         $promise->accept(['http_data' => $cli->body]);
     });
     $cli->isConnected = false;
     if (!$cli->errCode) {
         Timer::add($cli->sock, $this->timeout, function () use($cli, &$promise) {
             @$cli->close();
             if ($cli->isConnected) {
                 $promise->accept(['http_data' => null, 'http_error' => 'Http client read timeout']);
             } else {
                 $promise->accept(['http_data' => null, 'http_error' => 'Http client connect timeout']);
             }
         });
     }
 }
 public function run(Promise &$promise)
 {
     $cli = new \swoole_client(SWOOLE_TCP, SWOOLE_SOCK_ASYNC);
     $urlInfo = parse_url($this->url);
     $timeout = $this->timeout;
     if (!isset($urlInfo['port'])) {
         $urlInfo['port'] = 80;
     }
     $httpParser = new \HttpParser();
     $cli->on("connect", function ($cli) use($urlInfo, &$timeout, &$promise) {
         $cli->isConnected = true;
         $host = $urlInfo['host'];
         if ($urlInfo['port']) {
             $host .= ':' . $urlInfo['port'];
         }
         $req = array();
         $req[] = "GET {$this->url} HTTP/1.1\r\n";
         $req[] = "User-Agent: PHP swAsync\r\n";
         $req[] = "Host:{$host}\r\n";
         $req[] = "Connection:close\r\n";
         $req[] = "\r\n";
         $req = implode('', $req);
         $cli->send($req);
     });
     $cli->on("receive", function ($cli, $data = "") use(&$httpParser, &$promise) {
         $ret = $httpParser->execute($data);
         if ($ret !== false) {
             Timer::del($cli->sock);
             $cli->isDone = true;
             if ($cli->isConnected()) {
                 $cli->close();
             }
             $promise->accept(['http_data' => $ret]);
         }
     });
     $cli->on("error", function ($cli) use(&$promise) {
         Timer::del($cli->sock);
         $promise->accept(['http_data' => null, 'http_error' => 'Connect error']);
     });
     $cli->on("close", function ($cli) use(&$promise) {
     });
     if ($this->proxy) {
         $cli->connect($this->proxy['host'], $this->proxy['port'], 0.05);
     } else {
         $cli->connect($urlInfo['host'], $urlInfo['port'], 0.05);
     }
     $cli->isConnected = false;
     if (!$cli->errCode) {
         Timer::add($cli->sock, $this->timeout, function () use($cli, &$promise) {
             @$cli->close();
             if ($cli->isConnected) {
                 $promise->accept(['http_data' => null, 'http_error' => 'Http client read timeout']);
             } else {
                 $promise->accept(['http_data' => null, 'http_error' => 'Http client connect timeout']);
             }
         });
     }
 }
Exemple #3
0
 public function send(callable $callback)
 {
     $client = new \swoole_client(SWOOLE_SOCK_UDP, SWOOLE_SOCK_ASYNC);
     $client->on("connect", function ($cli) {
         $cli->send($this->data);
     });
     $client->on('close', function ($cli) {
     });
     $client->on('error', function ($cli) use($callback) {
         $cli->close();
         call_user_func_array($callback, array('r' => 1, 'key' => $this->key, 'calltime' => $this->calltime, 'error_msg' => 'conncet error'));
     });
     $client->on("receive", function ($cli, $data) use($callback) {
         //临时方案
         Timer::del($this->key);
         $cli->close();
         $this->calltime = microtime(true) - $this->calltime;
         //swoole_timer_clear($this ->timer);
         call_user_func_array($callback, array('r' => 0, 'key' => $this->key, 'calltime' => $this->calltime, 'data' => $data));
     });
     if ($client->connect($this->ip, $this->port, $this->timeout)) {
         $this->calltime = microtime(true);
         if (floatval($this->timeout) > 0) {
             //临时方案
             Timer::add($this->key, $this->timeout, $client, $callback, array('r' => 2, 'key' => $this->key, 'calltime' => $this->calltime, 'error_msg' => 'timeout'));
             /*
                     $this ->timer = swoole_timer_after(floatval($this ->timeout) * 1000, function() use($client,$callback){
                         $client ->close();
                         \SysLog::error(__METHOD__." TIMEOUT ", __CLASS__);
                         $this ->calltime = microtime(true) - $this ->calltime;
                         call_user_func_array($callback, array('r' => 2 ,'key' => '', 'calltime' => $this ->calltime, 'error_msg' => 'timeout'));
                     });
             */
         }
     }
 }
Exemple #4
0
 /**
  * [packRsp 组包合包,函数回调]
  * @param  [type] $cli  [description]
  * @param  [type] $data [description]
  * @return [type]       [description]
  */
 private function packRsp($cli, $data)
 {
     /*
        1.设置标记位,开始时,解析头部信息
        2.合并boty,两种头部协议
        3.特殊处理 重定向+超时
     */
     $this->buffer .= $data;
     //cookie 保持
     if ($this->persistCookies && isset($this->rspHeaders['set-cookie'])) {
         //TODO support
     }
     if ($this->trunk_length > 0 and strlen($this->buffer) < $this->trunk_length) {
         return;
     }
     if (empty($this->rspHeaders)) {
         $ret = $this->parseHeader($this->buffer);
         if ($ret === false) {
             return;
         } else {
             if ($this->handleRedirects && $this->rspHeaders['status'] >= 300 && $this->rspHeaders['status'] < 400) {
                 //超出最大循环
                 if (++$this->redirectCount >= $this->maxRedirects) {
                     $cli->close();
                     Timer::del($this->key);
                     \SysLog::error(__METHOD__ . " redirectCount over limit ", __CLASS__);
                     call_user_func_array($this->callback, array('r' => 1, 'key' => $this->key, 'calltime' => $this->calltime, 'data' => "redirectCount over limit"));
                     return false;
                 }
                 $location = isset($this->rspHeaders['location']) ? $this->rspHeaders['location'] : '';
                 $location .= isset($this->rspHeaders['uri']) ? $this->rspHeaders['uri'] : '';
                 if (!empty($location)) {
                     \SysLog::debug(__METHOD__ . " redirect location ", __CLASS__);
                     //TODO 尝试client内部重定
                     $url = parse_url($location);
                     $this->host = isset($url['host']) ? $url['host'] : $this->host;
                     $this->body = '';
                     $this->buffer = '';
                     $this->rspHeaders = array();
                     $this->isFinish = false;
                     $cli->close();
                     $http = $this->get($location);
                     $http->send($this->callback);
                     return;
                 } else {
                     $cli->close();
                     Timer::del($this->key);
                     \SysLog::error(__METHOD__ . " redirect location error  ", __CLASS__);
                     call_user_func_array($this->callback, array('r' => 1, 'key' => $this->key, 'calltime' => $this->calltime, 'data' => "redirect location error "));
                     return false;
                 }
             }
             //header + CRLF + body
             if (strlen($this->buffer) > 0) {
                 $parsebody = $this->parseBody();
             }
         }
     } else {
         $parsebody = $this->parseBody();
     }
     if ($parsebody === true and $this->isFinish) {
         $compress_type = empty($this->rspHeaders['content-encoding']) ? '' : $this->rspHeaders['content-encoding'];
         $this->body = self::gz_decode($this->body, $compress_type);
         $data = array('head' => $this->rspHeaders, 'body' => $this->body);
         $cli->close();
         $this->calltime = microtime(true) - $this->calltime;
         Timer::del($this->key);
         call_user_func_array($this->callback, array('r' => 0, 'key' => $this->key, 'calltime' => $this->calltime, 'data' => $data));
     }
 }