天天看点

我与鸟哥 Yar 的亲密接触揭开 Yar 神秘面纱

模块越来越多,业务越来越复杂,RPC 就上场了,在 PHP 的世界里,鸟哥的作品一直备受广大网友的青睐。下面一起学习下鸟哥的 PRC 框架 Yar 。

RPC 采用客户端/服务器模式。首先,客户机调用进程发送一个有进程参数的调用信息到服务进程,然后等待应答信息。在服务器端,进程保持睡眠状态直到调用信息的到达为止。当一个调用信息到达,服务器获得进程参数,计算结果,发送答复信息,然后等待下一个调用信息,最后,客户端调用进程接收答复信息,获得进程结果,然后调用执行继续进行。

这和我们外网 api 的原理不都一个样么?那么我们一起看看高大上的 Yar 是怎么在玩。

客户端代码,假设该服务设在局域网<code>10.211.55.4</code>上

服务器端代码

访问结果如下

实际呢,yar client 是通过<code>__call</code>这个魔术方法来实现远程调用的,在Yar_client类里面并没有任何方法,当我们在调用一个不存在的方式的时候,就会执行<code>__call</code>方法,这个在框架中非常常见。

我与鸟哥 Yar 的亲密接触揭开 Yar 神秘面纱

在 yar 中规定的传输协议如下图所示,请求体为82个字节的<code>yar_header_t</code>和8字节的打包名称和请求实体<code>yar_request_t</code>,在<code>yar_header_t</code>里面用<code>body_len</code>记录8字节的打包名称+请求实体的长度;返回体类似,只是实体内容的结构体稍微不同,在<code>reval</code>里面才是实际最后客户端需要的结果。

整个传输以二进制流的形式传送。

在<code>yar_transport.h</code>中,定义了<code>yar_transport_t</code>结构体,先不考虑并行处理的接口,以<code>socket</code>传输协议为例子学习,代码简化一些如下:

然后在<code>transports/socket.c</code>中定义了<code>yar_transport_socket</code>

整理了整体的执行流程如下图

我与鸟哥 Yar 的亲密接触揭开 Yar 神秘面纱

鸟哥在<code>yar_packager.c</code>中首先定义了一个结构体,初始化的时候会把各个<code>yar_packager_t</code>注册到<code>**packagers</code>数组中。

然后通过传入的<code>name</code>和<code>yar_packager_t</code>的<code>name</code>做比较,相同则返回该实例

亲密接触完毕。纸上得来终觉浅,绝知此事要躬行。这篇博客只能是辅助大家在看源码时一起分析,觉得不能抛开源码仅仅看这篇博客。

怎么样才能对这个内容真正的掌握呢,所以我有折腾了一个Java 版本的客户端,这样总算有所收获,这份代码也和我们平常写的业务逻辑还是有些区别,二进制的东西居多,整个过程下来对网络数据的传输有了更深刻的理解和学习哈。