嗨,老铁,欢迎来到我的博客!

如果觉得我的内容还不错的话,可以关注下我在 segmentfault.com 上的直播。我主要从事 PHP 和 Java 方面的开发,《深入 PHP 内核》作者之一。

[视频直播] PHP 进阶之路 - 亿级 pv 网站架构的技术细节与套路 直播中我将毫无保留的分享我这六年的全部工作经验和踩坑的故事,以及会穿插着一些面试中的 考点难点加分点

周梦康 发表于 2015-12-18 15296 次浏览 标签 : Yar

免费领取阿里云优惠券 我的直播 - 《PHP 进阶之路》

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

简介

Yar 是一个轻量级, 高效的 RPC 框架, 它提供了一种简单方法来让 PHP 项目之间可以互相远程调用对方的本地方法。

Yar 介绍 http://www.laruence.com/2012/09/15/2779.html

Yar 原始项目 https://github.com/laruence/yar

Yar Java Client 则实现了跨语言的远程调用。使得 Java 客户端能够调用 Yar PHP 服务器端本地的方法。并且支持同时调用多个远程服务的方法。

特性

  1. 执行速度快,框架轻,使用简单

  2. 支持并行的 RPC 调用

  3. Api 的使用和参数的和 PHP 版本保持一致

需求

运行环境 java 8

范例

PHP服务器端提供了服务

两个 rpc api ,模拟的业务场景是点赞赠送金币和发布帖子赠送金币。

<?php

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

	/**
	 * $uid 发布了帖子 $fid 
	 * @param $fid  interge
	 * @param $uid  interge
     * @return void
	 */
	public function post($uid,$fid){
		return "post:uid:$uid:fid:$fid";
	}
}

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

Java客户端同步调用这两个服务

public class YarClientTest extends TestCase {
    /**
     * 定义 rpc 接口
     */
    public interface RewardScoreService{
        String support(int uid,int fid);
        String post(int uid,int fid);
    }

    /**
     * rpc api 地址
     */
    static String uri = "http://mengkang.net/demo/yar-server/RewardScoreService.php";

    public void testUserService(){
        // 第一种调用方式
        YarClient yarClient  = new YarClient(uri);
        RewardScoreService rewardScoreService = (RewardScoreService) yarClient.useService(RewardScoreService.class);
        for (int i = 0; i < 10; i++) {
            System.out.println(rewardScoreService.support(1, 2));
        }
        // 第二种调用方式 增加配置参数集合
        YarClientOptions yarClientOptions = new YarClientOptions();
        yarClientOptions.setConnect_timeout(2000);
        YarClient yarClient2  = new YarClient(uri,yarClientOptions);
        RewardScoreService rewardScoreService2 = (RewardScoreService) yarClient2.useService(RewardScoreService.class);
        for (int i = 0; i < 10; i++) {
            System.out.println(rewardScoreService2.post(1, 20));
        }
    }

}

考虑到 Java 和 PHP 的数据类型的不同,这里做了一个折中的处理,返回数据类型客户端框架统一以Object类型接受,然后使用时再根据接口定义的数据类型进行转换。

Java客户端并行调用这两个服务

并发调用的 api 均按照 php c 扩展版本的 yar 协议为准 原版 api http://php.net/manual/zh/class.yar-concurrent-client.php

YarConcurrentClient.call方法注册,

YarConcurrentClient.loop并行调用,

YarConcurrentClient.reset清空任务。

回调函数需要继承实现YarConcurrentCallback里面定义了两个方法:async是针对并行调用发出之后立即执行的任务,而success则是每个请求之后返回的结果。

public class YarConcurrentClientTest extends TestCase {

    /**
     * rpc api 地址
     */
    static String uri = "http://mengkang.net/demo/yar-server/RewardScoreService.php";

    public class callback extends YarConcurrentCallback {

        public void async() {
            System.out.println("现在, 所有的请求都发出去了, 还没有任何请求返回");
        }

        public Object success() {
            return retValue;
        }

    }

    public class errorCallback extends YarConcurrentErrorCallback {
        @Override
        void error() {
            System.out.println("出错了");
        }
    }

    public void testLoop() throws Exception {

        String packagerName = YarConfig.getString("yar.packager");
        YarClientOptions yarClientOptions = new YarClientOptions();
        yarClientOptions.setConnect_timeout(2000);

        for (int i = 0; i < 10; i++) {
            // 第一种调用方式
            YarConcurrentClient.call(new YarConcurrentTask(uri, "support", new Object[]{1, 2}, packagerName, new callback()));
            // 第二种调用方式 增加一些额外配置选项
            YarConcurrentClient.call(new YarConcurrentTask(uri, "support", new Object[]{1, 2}, packagerName, new callback(),yarClientOptions));
        }

        for (int i = 0; i < 10; i++) {
            // 第三种调用方式 有正确的回调和错误的回调
            YarConcurrentClient.call(new YarConcurrentTask(uri,"post",new Object[]{1,2},packagerName,new callback(),new errorCallback()));
            // 第四种调用方式 在第三种的基础上增加额外的配置选项
            YarConcurrentClient.call(new YarConcurrentTask(uri,"post",new Object[]{1,2},packagerName,new callback(),new errorCallback(),yarClientOptions));
        }

        YarConcurrentClient.loop(new callback());
        YarConcurrentClient.reset();
    }
}

更多详细的使用请见项目 test下的 demo,尽量保证和原作者方法使用上的一致。

下载

Github https://github.com/zhoumengkang/yar-java-client

感谢

感谢好友 java 大神曾明明在开发过程中给我解答疑虑,感谢全栈基友李雄飞指点迷津。

嗨,老铁,欢迎来到我的博客!

如果觉得我的内容还不错的话,可以关注下我在 segmentfault.com 上的直播。我主要从事 PHP 和 Java 方面的开发,《深入 PHP 内核》作者之一。

[视频直播] PHP 进阶之路 - 亿级 pv 网站架构的技术细节与套路 直播中我将毫无保留的分享我这六年的全部工作经验和踩坑的故事,以及会穿插着一些面试中的 考点难点加分点

评论列表