我与鸟哥 Yar 的亲密接触

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

揭开 Yar 神秘面纱

RPC 采用客户端/服务器模式。首先,客户机调用进程发送一个有进程参数的调用信息到服务进程,然后等待应答信息。在服务器端,进程保持睡眠状态直到调用信息的到达为止。当一个调用信息到达,服务器获得进程参数,计算结果,发送答复信息,然后等待下一个调用信息,最后,客户端调用进程接收答复信息,获得进程结果,然后调用执行继续进行。
这和我们外网 api 的原理不都一个样么?那么我们一起看看高大上的 Yar 是怎么在玩。

Yar 功能演示

客户端代码,假设该服务设在局域网10.211.55.4

<?php

class RpcClient {
    // RPC 服务地址映射表
    public static $rpcConfig = array(
        "RewardScoreService"    => "http://10.211.55.4/yar/server/RewardScoreService.class.php",
    );

    public static function init($server){
        if (array_key_exists($server, self::$rpcConfig)) {
            $uri = self::$rpcConfig[$server];
            return new Yar_Client($uri);
        }
    }
}

$RewardScoreService = RpcClient::init("RewardScoreService");
var_dump($RewardScoreService->support(1, 2));

服务器端代码

<?php

class RewardScoreService {
    /**
     * $uid 给 $feedId 点赞
     * @param $feedId  interge
     * @param $uid  interge
     * @return void
     */
    public function support($uid,$feedId){
        return "uid = ".$uid.", feedId = ".$feedId;
    }
}

$yar_server = new Yar_server(new RewardScoreService());
$yar_server->handle();

访问结果如下

uid = 1, feedId = 2

Yar 远程调用的实现原理

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

Yar 协议分析

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

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

Yar 数据传输的整体流程分析

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

typedef struct _yar_transport_interface {
    void *data;
    int  (*open)(struct _yar_transport_interface *self, char *address, uint len, long options, char **msg TSRMLS_DC);
    int  (*send)(struct _yar_transport_interface *self, struct _yar_request *request, char **msg TSRMLS_DC);
    struct _yar_response * (*exec)(struct _yar_transport_interface *self, struct _yar_request *request TSRMLS_DC);
    int  (*setopt)(struct _yar_transport_interface *self, long type, void *value, void *addition TSRMLS_DC);
    int  (*calldata)(struct _yar_transport_interface *self, yar_call_data_t *calldata TSRMLS_DC);
    void (*close)(struct _yar_transport_interface *self TSRMLS_DC);
} yar_transport_interface_t;

typedef struct _yar_transport {
    const char *name;
    struct _yar_transport_interface * (*init)(TSRMLS_D);
    void (*destroy)(yar_transport_interface_t *self TSRMLS_DC);
    yar_transport_multi_t *multi;
} yar_transport_t;

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

yar_transport_t yar_transport_socket = {
    "sock",
    php_yar_socket_init,
    php_yar_socket_destroy,
};

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

Yar 数据的打包和解包

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

struct _yar_packagers_list {
    unsigned int size;
    unsigned int num;
    yar_packager_t **packagers;
} yar_packagers_list;
typedef struct _yar_packager {
    const char *name;
    int  (*pack) (struct _yar_packager *self, zval *pzval, smart_str *buf, char **msg TSRMLS_DC);
    zval * (*unpack) (struct _yar_packager *self, char *content, size_t len, char **msg TSRMLS_DC);
} yar_packager_t;

然后通过传入的nameyar_packager_tname做比较,相同则返回该实例

PHP_YAR_API yar_packager_t * php_yar_packager_get(char *name, int nlen TSRMLS_DC) /* {{{ */ {
    int i = 0;
    for (;i<yar_packagers_list.num;i++) {
        if (strncasecmp(yar_packagers_list.packagers[i]->name, name, nlen) == 0) {
            return yar_packagers_list.packagers[i];
        }
    }

    return NULL;
} /* }}} */

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

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

Github 项目地址: https://github.com/zhoumengkang/yar-java-client

时间: 2024-09-14 16:30:37

我与鸟哥 Yar 的亲密接触的相关文章

《鸟哥的Linux 私房菜 基础学习篇(第三版)》——1.2 Torvalds的Linux开发

1.2 Torvalds的Linux开发 鸟哥的Linux 私房菜 基础学习篇(第三版) 我们前面一节当中,提到了UNIX的历史,也提到了Linux是由芬兰人Torvalds所开发的.那么为何托瓦兹可以开发Linux呢?凭空想象而来的,还是有什么渊源?这里我们就来谈一谈! 1.2.1 Minix Linus Torvalds(托瓦兹, 1969年出生)的外祖父是赫尔辛基大学的统计学家,他的外祖父为了让自己的小孙子能够学点东西,所以从小就将托瓦兹带到身边来管理一些微计算机.在这个时期,托瓦兹接触了

《鸟哥的Linux 私房菜 基础学习篇(第三版)》——0.2 个人计算机架构与接口设备

0.2 个人计算机架构与接口设备 鸟哥的Linux 私房菜 基础学习篇(第三版) 一般消费者常说的计算机通常指的就是x86的个人计算机架构,因此我们有必要来了解一下这个架构的各个组件.事实上,Linux最早在发展的时候,就是依据个人计算机的架构来发展的,所以,真的需要了解一下.另外,因为两大主流x86开发商(Intel, AMD)的CPU架构并不兼容,而且设计理念也有所区别,所以两大主流CPU所需要的主板芯片组设计也就不太相同.目前最新的主板架构主要如图0-4所示. 就如同前一节提到的,整个主板

《鸟哥的Linux 私房菜 基础学习篇(第三版)》——第1章 Linux是什么 1.1Linux是什么

第1章 Linux是什么 众所皆知,Linux的内核原型是1991年由托瓦兹(Linus Torvalds)写出来的,但是托瓦兹为何可以写出Linux这个操作系统?为什么他要选择386的计算b机来开发?为什么Linux的开发可以这么迅速?又为什么Linux是免费的?以及目前为何有这么多的Linux版本(distributions)呢?了解这些后,我们才能够知道为何Linux可以免除专利软件之争,并且了解到Linux为何可以同时在个人计算机与大型主机上面大放光彩.所以,在进入Linux的世界之前,

从零开始与网站开发亲密接触

从零开始与网站开发亲密接触 去年我接手第一个网站项目开发时,并没有做网站的经验,只能试着按照以前我参与做Microsoft Office时的方法来做: 首先是打造一个便于公司内部沟通交流的内部网,其中包含"传统软件"研发需要的三个工具:文档库(存放公司各项目的文档).CVS(保存项目的各种源代码).BugFree(记录项目的各种缺陷). 然后,抓住"需求.开发.测试"三个环节: 1 要做好规划.明确需求.为什么要做这个网站.要达到什么目标?特别是需求,要详细到每个页

Photoshop教程02:亲密接触Photoshop6

教程 跟Photoshop6约会结束来,想不想再来一次亲密接触呢?不要着急,往下看! 一目了然的选项栏 Photoshop6.0的操作界面有了较大的改变,重要的变化是添加了选项栏,其功能相当 图2-01 画笔调板,在Photoshop6.0画笔调板已经成为画笔工具的一个选项,画笔的设置和各种选项也在画笔工具的选项栏中完成,如图2-02所示. 图2-02 图像以前的编辑菜单下的数字变形命令指定图像旋转和缩放比例变为变形命令的选项栏来完成,如图2-03所示. 图2-03 制作优秀的网络图像 各位是不

亲密接触ASP.Net(16) Cookie

Cookie Cookie的用法也和ASP中差不多.比如我们建立一个名为aspcn,值为飞刀的cookie HttpCookie cookie = new HttpCookie["aspcn"];cookie.Value = "飞刀";Response.AppendCookie(cookie); 我们取出Cookie值也很简单 HttpCookie cookie = Request.Cookies["aspcn"];cookieValue = c

《鸟哥的Linux私房菜》13章shel script习题答案

 因为感觉对Linux命令还没有多大的感觉,所以就专门找了鸟哥的书来看一下,折腾了几天看基础篇的shell部分,收获还是蛮大的,至少对Linux命令是有点感觉了,然后往前学习的一些知识,在理论知识方面也得到了一定的扩充了.先不多说,把习题的答案分享一下. <鸟哥的Linux私房菜>基础篇P398习题 (1)请新建一个script,当你执行该script的时候,该script可以显示你目前的身份(用whoami)和你目前所在的目录(用pwd). 这道题的答案已经直接给出了,直接上脚本: 1 2

《鸟哥的Linux 私房菜 基础学习篇(第三版)》——导读

前言 本书是最具知名度的Linux入门书<鸟哥的Linux私房菜基础学习篇>的最新版,全面而详细地介绍了Linux操作系统.全书分为5个部分:第一部分着重说明Linux的起源及功能,如何规划和安装Linux主机:第二部分介绍Linux的文件系统.文件.目录与磁盘的管理:第三部分介绍文字模式接口shell和管理系统的好帮手shell脚本,另外还介绍了文字编辑器vi和vim的使用方法:第四部分介绍了对于系统安全非常重要的Linux账号的管理,以及主机系统与程序的管理,如查看进程.任务分配和作业管理

拒绝从入门到放弃_《鸟哥的 Linux 私房菜 — 基础学习篇(第三版)》必读目录

目录 目录 前言 关于这本书 必看知识点 最后 前言 相信部分刚进入这个行业的新同学会对一个问题感到疑惑,为什么从培训学校出来的学员不被欢迎? 这里记录下一些我个人的看法(博主也曾有面试新员工的经历):说到底还是一个学习能力的问题.就这一点,从我的经历看来(曾到多家企业培训新人),培训出身的技术人员大体而言确实没有科班出身的学得更快准狠一些.学习能力这个东西其实比较虚,它并没有一个直观的考量方式,所以企业一般都会简单粗暴的使用学历.专业.项目经验来衡量.这之间反映了你的计算机知识框架是否完善.基