当前位置: 首页 > 后端技术 > PHP

PHP教父鸟哥亚尔原理解析

时间:2023-03-30 00:08:24 PHP

小弟的直播分享点赞加收藏还敢报名吗?绝对有干货和惊喜!一份早餐钱的投资可能会让你的薪水翻倍或开阔你的视野!PHP进阶之路-亿级光伏网站架构技术细节与套路PHP进阶之路-亿级光伏网站架构实战性能榨取有很多,业务越来越复杂,于是RPC就派上用场了。在PHP的世界里,Bird的作品一直受到广大网友的青睐。下面来了解一下鸟哥的PRC框架Yar。揭秘YarRPC使用客户端/服务器模型。首先,客户端调用进程向服务进程发送带有进程参数的调用消息,然后等待回复消息。在服务器端,进程一直处于休眠状态,直到调用消息到达。当调用消息到达时,服务器获取流程参数,计算结果,发送回复消息,然后等待下一个调用消息。最后客户端调用进程收到回复消息,得到处理结果,然后调用继续执行。这不是和我们外网api一样的原理吗?那么我们就来看看高大上的Yar是怎么玩的吧。Yar函数演示客户端代码,假设服务设置在局域网10.211.55.4"http://10.211.55.4/yar/server/RewardScoreService.class.php",);publicstaticfunctioninit($server){if(array_key_exists($server,self::$rpcConfig)){$uri=self::$rpcConfig[$server];返回新的Yar_Client($uri);}}}$RewardScoreService=RpcClient::init("RewardScoreService");var_dump($RewardScoreService->support(1,2));服务器代码handle();访问结果如下:uid=1,feedId=2Yar远程调用的实际实现原理是yarclient是通过__call是一个神奇的方法实现远程调用,不在Yar_client类中任何方法,当我们调用不存在的方法时,都会执行__call方法,框架中很常见yar协议解析yar中指定的传输协议如下图所示,请求体为82字节yar_header_t和8字节包名以及请求实体yar_request_t,使用body_len记录8字节包名+yar_header_t中请求实体的长度;返回体类似,只是实体内容的结构略有不同,是在reval客户端实际需要的最终结果。整个传输以二进制流的形式传送。Yar数据传输整体流程分析在yar_transport.h中,定义了yar_transport_t结构体,先不考虑并行处理的接口。以socket传输协议为例进行学习,代码简化如下:typedefstruct_yar_transport_interface{void*data;int(*open)(struct_yar_transport_interface*self,char*address,uintlen,longoptions,char**msgTSRMLS_DC);int(*send)(struct_yar_transport_interface*self,struct_yar_request*request,char**msgTSRMLS_DC);struct_yar_response*(*exec)(struct_yar_transport_interface*self,struct_yar_request*requestTSRMLS_DC);int(*setopt)(struct_yar_transport_interface*self,longtype,void*value,void*additionTSRMLS_DC);int(*calldata)(struct_yar_transport_interface*self,yar_call_data_t*calldataTSRMLS_DC);void(*close)(struct_yar_transport_interface*selfTSRMLS_DC);}yar_transport_interface_t;typedefstruct_yar_transport{constcharLS*名称;)(yar_transport_interface_t*selfTSRMLS_DC);yar_transport_multi_t*multi;}yar_transport_t;然后在transports/socket.c中定义yar_transport_socketyar_transport_tyar_transport_socket={"sock",php_yar_socket_init,php_yar_socket_destroy,};在.c中先定义一个结构体,初始化时每个yar_packager_t都会注册到**packagers数组中struct_yar_packagers_list{unsignedint大小;无符号整数;yar_packager_t**packagers;}yar_packagers_list;typedefstruct_yar_packager{constchar*name;int(*pack)(struct_yar_packager*self,zval*pzval,smart_str*buf,charmsgTSRMLS_DC);zval*(*unpack)(struct_yar_packager*self,char*content,size_tlen,char**msgTSRMLS_DC);}yar_packager_t;然后比较传入的名字和yar_packager_t的名字,如果相同,返回ExamplePHP_YAR_APIyar_packager_t*php_yar_packager_get(char*name,intnlenTSRMLS_DC)/*{{{*/{inti=0;对于(;iname,name,nlen)==0){returnyar_packagers_list.packagers[i];}}returnNULL;}/*}}}*/完成亲密接触。纸上谈兵的成果总是肤浅的,我知道这件事必须要做。本博客只能辅助大家在看源码的时候一起分析。感觉不能只看这篇博客不留源码。怎么才能真正把握住这个内容呢,所以折腾了一个Java版的客户端,所以总算是有所收获,这段代码也和我们平时写的业务逻辑有些不一样,大部分都是二进制的东西,整个过程之后,让我对网络数据传输有了更深刻的理解和学习。Github项目地址:https://github.com/zhoumengka...