这篇我们分析swoole_client客户端读取数据的过程,从connect过程的代码可以看出,swClient在connect过程中设置了各种其他动作的回调函数,这里我们分析swoole_client的recv函数的主流程,同时把底层回调函数实现也关注下。
目前swoole客户端支持业务侧设置拆包策略,这里所谓的拆包是指,TCP是流式协议,也就是没有边界的概念,这个边界往往是由业务去确定的,类似头部占用多少个字节,body占用多少个字节,这个过程可以在PHP业务侧做,这时就需要多次读取扩展函数来获取余下的数据,目前swoole底层也支持这种拆包策略,通过swoole_client设置了包的边界策略,则recv时获取到的数据就是完整的一个业务包,下面recv过程整体比较简单,不做分析,有疑问,可以留言。
//swoole_client的recv函数
static PHP_METHOD(swoole_client, recv)
{
zend_long buf_len = SW_PHP_CLIENT_BUFFER_SIZE;
zend_long flags = 0;
int ret;
char *buf = NULL;
//输入参数解析
#ifdef FAST_ZPP
ZEND_PARSE_PARAMETERS_START(0, 2)
Z_PARAM_OPTIONAL
Z_PARAM_LONG(buf_len)
Z_PARAM_LONG(flags)
ZEND_PARSE_PARAMETERS_END();
#else
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|ll", &buf_len, &flags) == FAILURE)
{
return;
}
#endif
//waitall
if (flags == 1)//flags为1表示等待所有数据到达后返回
{
flags = MSG_WAITALL;
}
swClient *cli = client_get_ptr(getThis() TSRMLS_CC);//获取swoole内部封装的对象信息swClient
if (!cli)//获取失败
{
RETURN_FALSE;
}
swProtocol *protocol = &cli->protocol;//获取协议相关信息
if (cli->open_eof_check)//判断是否打开了eof检查
{
if (cli->buffer == NULL)//buffer为空
{
cli->buffer = swString_new(SW_BUFFER_SIZE_BIG);//申请buffer空间
}
swString *buffer = cli->buffer;
int eof = -1;
if (buffer->length