public function send(callable $callback) { $client = new \swoole_client(SWOOLE_SOCK_TCP, 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) { $this->calltime = microtime(true) - $this->calltime; $cli->close(); 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, 1)) { $this->calltime = microtime(true); if (floatval($this->timeout) > 0) { $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')); }); } } }
public function onReceive($server, $clientId, $fromId, $data) { $data = Yaaf::unpackAll($data); SysLog::notice(__METHOD__ . " fd = {$clientId} fromId = {$fromId} data = " . print_r($data, true), __CLASS__); $info = $server->connection_info($clientId, $fromId); //yaaf 协议 路由 $req = YaafHelper::yaafReqHandle($data); SysLog::info(__METHOD__ . print_r($req, true), __CLASS__); //路由失败 直接返回错误 if ($req['r'] === YaafHelper::YAAF_ERROR_CMD) { //todo 协议搞成yaaf $yaaf_data = Yaaf::packHeader() . Yaaf::packBody(array('errCode' => -1, 'errMsg' => 'not found class')); $server->sendto($info['remote_ip'], $info['remote_port'], $yaaf_data); return; } $class = $req['route']['controller'] . 'Controller'; $fun = 'action' . $req['route']['action']; //判断类是否存在 if (!class_exists($class) || !method_exists($class, $fun)) { SysLog::error(__METHOD__ . print_r($req, true), __CLASS__); $yaaf_data = Yaaf::packHeader() . Yaaf::packBody(array('errCode' => -1, 'errMsg' => 'not found class')); $server->sendto($info['remote_ip'], $info['remote_port'], $yaaf_data); return; } $obj = new $class($this->server, array('request' => $data, 'info' => $info), $clientId); //代入参数 $server->scheduler->newTask($obj->doFun($fun)); $server->scheduler->run(); }
public function onRequest($request, $response) { //SysLog::debug(__METHOD__ . print_r($request,true), __CLASS__); //统一进行路由和数据的预处理 $req = HttpHelper::httpReqHandle($request); // SysLog::info(__METHOD__.print_r($req,true),__CLASS__); if ($req['r'] === HttpHelper::HTTP_ERROR_URI) { $response->status(404); //todo:log $response->end("not found"); return; } //SysLog::info(__METHOD__.' '.__LINE__ . " REQUEST IS ".print_r($req,true),__CLASS__); $class = $req['route']['controller'] . 'Controller'; $fun = 'action' . $req['route']['action']; //判断类是否存在 if (!class_exists($class) || !method_exists($class, $fun)) { $response->status(404); SysLog::error(__METHOD__ . " class or fun not found class == {$class} fun == {$fun}", __CLASS__); $response->end("uri not found"); return; } $obj = new $class($this->server, array('request' => $req['request'], 'response' => $response), $request->fd); //代入参数 $request->scheduler->newTask($obj->{$fun}()); $request->scheduler->run(); }
public function setMethod($method) { // Manually set the request method (not usually needed). if (!in_array($method, array("GET", "POST", "PUT", "DEL" . "ETE"))) { \SysLog::error(__METHOD__ . ' valid method : ' . $method, __CLASS__); return false; } $this->method = $method; return true; }
private function test() { $test = new TestModel(); $res = (yield $test->MysqlMuticallTest()); SysLog::info(__METHOD__ . " res == " . print_r($res, true), __CLASS__); if ($res['r'] == 0) { //yield success SysLog::info(__METHOD__ . " yield success data == " . print_r($res['data'], true), __CLASS__); (yield $res); } else { //yield failed SysLog::error(__METHOD__ . " yield failed res == " . print_r($res, true), __CLASS__); (yield array('r' => 1, 'error_msg' => 'yield failed')); } }
/** * [createClient description] * @return [type] [description] */ public function createClient($ip, $port, $data, $timeout, $protocolType) { switch ($protocolType) { case 'udp': $client = new UDP($ip, $port, $data, $timeout); break; case 'tcp': $client = new TCP($ip, $port, $data, $timeout); break; default: \SysLog::error(__METHOD__ . " protocolType valid ==> {$protocolType}", __CLASS__); return false; break; } return $client; }
/** * [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)); } }
/** * [run 协程调度] * @param Generator $gen [description] * @return [type] [description] */ public function run(\Generator $gen) { while (true) { try { /* 异常处理 */ if ($this->exception) { $gen->throw($this->exception); $this->exception = null; continue; } $value = $gen->current(); \SysLog::info(__METHOD__ . " value === " . print_r($value, true), __CLASS__); /* 中断内嵌 继续入栈 */ if ($value instanceof \Generator) { $this->corStack->push($gen); \SysLog::info(__METHOD__ . " corStack push ", __CLASS__); $gen = $value; continue; } /* if value is null and stack is not empty pop and send continue */ if (is_null($value) && !$this->corStack->isEmpty()) { \SysLog::info(__METHOD__ . " values is null stack pop and send", __CLASS__); $gen = $this->corStack->pop(); $gen->send($this->callbackData); continue; } if ($value instanceof Swoole\Coroutine\RetVal) { // end yeild \SysLog::info(__METHOD__ . " yield end words == " . print_r($value, true), __CLASS__); return false; } /* 中断内容为异步IO 发包 返回 */ if (is_subclass_of($value, 'Swoole\\Client\\Base')) { //async send push gen to stack $this->corStack->push($gen); $value->send(array($this, 'callback')); return; } /* 出栈,回射数据 */ if ($this->corStack->isEmpty()) { return; } \SysLog::info(__METHOD__ . " corStack pop ", __CLASS__); $gen = $this->corStack->pop(); $gen->send($value); } catch (\Exception $e) { if ($this->corStack->isEmpty()) { /* throw the exception */ \SysLog::error(__METHOD__ . " exception ===" . $e->getMessage(), __CLASS__); return; } } } }