Example #1
0
 protected function process($data)
 {
     JmTextStatistic::tick();
     $class_name = '\\Handler\\' . $data['class'];
     $_SERVER['REMOTE_ADDR'] = $this->getRemoteIp();
     try {
         // 请求开始时执行的函数,on_request_start一般在bootstrap初始化
         if (function_exists('on_phpserver_request_start')) {
             \on_phpserver_request_start();
         }
         if (class_exists($class_name)) {
             $call_back = array(new $class_name(), $data['method']);
             if (is_callable($call_back)) {
                 $ctx = call_user_func_array($call_back, $data['params']);
             } else {
                 throw new Exception("method {$class_name}::{$data['method']} not exist");
             }
         } else {
             throw new Exception("class {$class_name} not exist");
         }
     } catch (Exception $ex) {
         $ctx = array('exception' => array('class' => get_class($ex), 'message' => $ex->getMessage(), 'code' => $ex->getCode(), 'file' => $ex->getFile(), 'line' => $ex->getLine(), 'traceAsString' => $ex->getTraceAsString()));
     }
     // 请求结束时执行的函数,on_request_start一般在bootstrap中初始化
     if (function_exists('on_phpserver_request_finish')) {
         // 这里一般是关闭数据库链接等操作
         \on_phpserver_request_finish();
     }
     JmTextStatistic::report($data, $ctx, $this->getRemoteIp());
     $this->send($ctx);
 }
Example #2
0
 /**
  * 业务处理(non-PHPdoc)
  * @see PHPServerWorker::dealProcess()
  */
 public function dealProcess($recv_str)
 {
     // 拷贝一份数据包,用来记录日志
     $recv_str_copy = $recv_str;
     // 统计监控记录请求开始时间点,后面用来统计请求耗时
     StatisticHelper::tick();
     // 清除上下文信息
     \Thrift\Context::clear();
     // 服务名
     $serviceName = $this->serviceName;
     // 本地调用方法名
     $method_name = 'none';
     // 来源ip
     $source_ip = $this->getRemoteIp();
     // 尝试读取上下文信息
     try {
         // 去掉TFrameTransport头
         $body_str = substr($recv_str, 4);
         // 读上下文,并且把上下文数据从数据包中去掉
         \Thrift\ContextReader::read($body_str);
         // 再组合成TFrameTransport报文
         $recv_str = pack('N', strlen($body_str)) . $body_str;
         // 如果是心跳包
         if (\Thrift\Context::get('isHeartBeat') == 'true') {
             $thriftsocket = new \Thrift\Transport\TBufferSocket();
             $thriftsocket->setHandle($this->connections[$this->currentDealFd]);
             $thriftsocket->setBuffer($recv_str);
             $framedTrans = new \Thrift\Transport\TFramedTransport($thriftsocket);
             $protocol = new Thrift\Protocol\TBinaryProtocol($framedTrans, false, false);
             $protocol->writeMessageBegin('#$%Heartbeat', 2, 0);
             $protocol->writeMessageEnd();
             $protocol->getTransport()->flush();
             return;
         }
     } catch (Exception $e) {
         // 将异常信息发给客户端
         $this->writeExceptionToClient($method_name, $e, self::getProtocol(\Thrift\Context::get('protocol')));
         // 统计上报
         StatisticHelper::report($serviceName, $method_name, $source_ip, $e, $recv_str_copy);
         return;
     }
     // 客户端有传递超时参数
     if (($timeout = \Thrift\Context::get("timeout")) && $timeout >= 1) {
         pcntl_alarm($timeout);
     }
     // 客户端有传递服务名
     if (\Thrift\Context::get('serverName')) {
         $serviceName = \Thrift\Context::get('serverName');
     }
     // 尝试处理业务逻辑
     try {
         // 服务名为空
         if (!$serviceName) {
             throw new \Exception('Context[serverName] empty', 400);
         }
         // 如果handler命名空间为provider
         if ($this->handlerNamespace == 'Provider') {
             $handlerClass = $this->handlerNamespace . '\\' . $serviceName . '\\' . $serviceName . 'Handler';
         } else {
             $handlerClass = $this->handlerNamespace . '\\' . $serviceName;
         }
         // processor
         $processorClass = $this->providerNamespace . '\\' . $serviceName . '\\' . $serviceName . 'Processor';
         // 文件不存在尝试从磁盘上读取
         if (!class_exists($handlerClass, false)) {
             clearstatcache();
             if (!class_exists($processorClass, false)) {
                 require_once $this->providerDir . '/' . $serviceName . '/Types.php';
                 require_once $this->providerDir . '/' . $serviceName . '/' . $serviceName . '.php';
             }
             $handler_file = $this->handlerNamespace == 'Provider' ? $this->handlerDir . '/' . $serviceName . '/' . $serviceName . 'Handler.php' : $this->handlerDir . '/' . $serviceName . '.php';
             if (is_file($handler_file)) {
                 require_once $handler_file;
             }
             if (!class_exists($handlerClass)) {
                 throw new \Exception('Class ' . $handlerClass . ' not found', 404);
             }
         }
         // 运行thrift
         $handler = new $handlerClass();
         $processor = new $processorClass($handler);
         $pname = \Thrift\Context::get('protocol') ? \Thrift\Context::get('protocol') : 'binary';
         $protocolName = self::getProtocol($pname);
         $thriftsocket = new \Thrift\Transport\TBufferSocket();
         $thriftsocket->setHandle($this->connections[$this->currentDealFd]);
         $thriftsocket->setBuffer($recv_str);
         $framedTrans = new \Thrift\Transport\TFramedTransport($thriftsocket, true, true);
         $protocol = new $protocolName($framedTrans, false, false);
         $protocol->setTransport($framedTrans);
         // 请求开始时执行的函数,on_request_start一般在bootstrap初始化
         if (function_exists('on_phpserver_request_start')) {
             \on_phpserver_request_start();
         }
         $processor->process($protocol, $protocol);
         // 请求结束时执行的函数,on_request_start一般在bootstrap中初始化
         if (function_exists('on_phpserver_request_finish')) {
             // 这里一般是关闭数据库链接等操作
             \on_phpserver_request_finish();
         }
         $method_name = $protocol->fname;
     } catch (Exception $e) {
         // 异常信息返回给客户端
         $method_name = !empty($protocol->fname) ? $protocol->fname : 'none';
         $this->writeExceptionToClient($method_name, $e, !empty($protocolName) ? $protocolName : 'Thrift\\Protocol\\TBinaryProtocol');
         StatisticHelper::report($serviceName, $method_name, $source_ip, $e, $recv_str_copy);
         return;
     }
     // 统计上报
     StatisticHelper::report($serviceName, $method_name, $source_ip);
 }