dubbo-php-framework的Protocol解析(二)

版权声明:转载请注明来源 https://blog.csdn.net/u013702678/article/details/82730353

前面一篇Protocol解析的文章主要介绍了Protocol的继承体系和一些默认实现,其实从分析中可以看出默认实现几乎什么都没做,核心实现在Protocol的核心子类FSOFProtocol中,其路径为dubbo-php-framework-master/provider/fsof/FSOFProtocol.php,这篇我们就开始分析FSOFProtocol的实现。

public function init()
    {
        $this->logger = \Logger::getLogger(__CLASS__);
        $this->parser = new DubboParser();//声明请求解析器,这里声明为DubboParser。
    }
//检查buffer容量
public function checkBuffer($client_id, $data)
    {
        //检测头,这里逻辑后续展开再分析
        $request = $this->checkHeader($client_id, $data);
        //头部信息不正确
        if ($request === false)
		{
            if (empty($this->buffer_header[$client_id]))//当前clientid没有任何头部数据信息,则表示异常,返回错误丢弃此包即可。
			{
                $this->logger->error("fsof header err.");
                return self::STATUS_ERROR;
            }
			else//当前clientid有头部数据信息,只是不完整,这里继续等待
			{
                $this->logger->debug("wait head data. fd={$client_id}");
                return self::STATUS_WAIT;
            }
        }

        //请求的数据长度信息小于等于目前已经接收到的数据长度,也就是接收到的数据能组成至少一个完整的数据包。
        if ($request->getRequestLen() <= strlen($request->getFullData()))
		{
            //解析这个请求判断是否是心跳包
			if($this->parser->isHearBeatRequest($request))
			{
				//心跳机制
				return self::STATUS_FINISH;
			}
			else
			{
                //判断是否是完整的一个数据包体
				if ($this->parser->parseRequestBody($request))
				{
                    $this->logger->debug("parse request ok!");
					return self::STATUS_FINISH;
				}
				else//其他异常情况
				{
                    $this->logger->error("fsof body err.");
					return self::STATUS_ERROR;
				}
			}
        }
		else//其他情况,继续等待
		{
            $this->logger->debug("wait body data. fd={$client_id}");
            return self::STATUS_WAIT;
        }
    }
//检查头部信息
private function checkHeader($client_id, $fsof_data)
    {
    	$request = NULL;
        if (!isset($this->requests[$client_id]))//没有这个clientid的请求信息,标明是个新请求
		{
			//新连接
            $this->logger->debug("new request from {$client_id}");
            if (!empty($this->buffer_header[$client_id]))//buffer_head以clientId为维度建立内存缓存数据,这里不为空,表示已经有数据到来过。
			{
                $fsof_data = $this->buffer_header[$client_id].$fsof_data;//记录新的数据
            }
            //完全纯新的数据到来
            $this->buffer_header[$client_id] = $fsof_data;

            //数据长度还不够,协议的包头长度为16byte
            if (strlen($fsof_data) < DubboParser::PACKAGE_HEDA_LEN)
			{
                return false;
            }
			else//数据长度是够的
			{
                unset($this->buffer_header[$client_id]);//清理这个clientid的头部数据缓存
                $request = new DubboRequest();//声明DubboRequest的对象来记录这个请求信息
                $request->setFullData($fsof_data);//记录接收到的数据
                $request = $this->parser->parseRequestHeader($request);//解析这个数据
                //解析失败
                if ($request == false)
				{
                    $this->logger->error("parse request Header fail. fsof_data=" . $fsof_data);
                    return false;
                }

                $this->logger->debug("create one request for {$client_id}");
                $this->requests[$client_id] = $request;//保存请求
            }
        }
		else//已经有这个请求的缓存了
		{
            $this->logger->debug("append request data for {$client_id}");
            $request = $this->requests[$client_id];
            $request->setFullData($fsof_data);//缓存记录数据
        }

        return $request;
    }

猜你喜欢

转载自blog.csdn.net/u013702678/article/details/82730353
今日推荐