前面一篇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;
}