标签:phprpc

浏览模式: 标准 | 列表 | 图文
hprose使用中的一個問題

hprose使用中的一個問題

什麼是hprose?這個我不想多說了,只想說它之前的版本叫phprpc,這是它的更新版,功能更強大。
官方地址是http://www.hprose.com。
以前用用都還行,結果就昨天在使用的時候發現,調用同樣的接口時,服務器返回502錯誤。但有時候確實是正常的。
仔細查看了一下,好象是返回的數據過大,於是我使用serialize將數組序列化後,用strlen查看了一下長度,發現長度在99999左右(這個數字當然是不對的,但大小差不多),最多也就99K嘍。但正因為這樣會出錯。於是我一點一點試
我在遠程的函數裏str_repeat("0",1111),一直嘗試,發現當數字在7000多時,就返回502了。因為是采用了php-fpm方式,所以我在本地的apache服務器上做了個測試,發現大約是在9000多字節。鬱悶。
問了一下andot,他說可能是服務器的設置也問題,也可能正好是一個BUG。但短時間內沒有時間測試了。

鬱悶

-----

时隔多日,这个BUG已经在一年前就解决了。只是我没有更新。andot居然来回复了一下,我想,我还是更新掉本文吧。

在Yii框架中使用Hprose或PHPRPC

在Yii框架中使用Hprose或PHPRPC

Yii:

Yii is a high-performance PHP framework best for developing Web 2.0 applications.

Yii comes with rich features: MVC, DAO/ActiveRecord, I18N/L10N, caching, authentication and role-based access control, scaffolding, testing, etc. It can reduce your development time significantly.

PHPRPC:

PHPRPC 是一个轻型的、安全的、跨网际的、跨语言的、跨平台的、跨环境的、跨域的、支持复杂对象传输的、支持引用参数传递的、支持内容输出重定向的、支持分级错误处理的、支持会话的、面向服务的高性能远程过程调用协议。

目前该协议的最新版本为 3.0。该版本目前已有以下几种语言的实现:

ASP,ActionScript,Delphi/C++Builder/Kylix,Java,JavaScript,NET,PHP,Python,Ruby,Perl,Lazarus(Free Pascal)

其中 ASP、.NET、Java、Ruby、Python 和 PHP 版本除了提供客户端实现外,还提供了服务器端实现。

HPROSE:

Hprose (High Performance Remote Object Service Engine) 是一个商业开源的新型轻量级跨语言跨平台的面向对象的高性能远程动态通讯中间件。它支持众多语言,例如 C++, .NET, Java, Delphi, Objective-C, ActionScript, JavaScript, ASP, PHP, Python, Ruby, Perl 等语言,通过 Hprose 可以在这些语言之间实现方便且高效的互通。

Hprose 易学易用,且功能强大,您只需很短时间的学习,就可以用它方便地构建出跨语言跨平台分布式的电信级应用系统。

如何在Yii中使用Hprose或者PHPRPC呢?我这里简单介绍一下Yii下hprose的应用方法

1、下载hprose的PHP版本,嗯,别看了,是混淆过的,但不影响你使用。

2、将下载后的hprose拷贝到yii项目的/protected/extension/hprose目录下

3、新建一个apicontroller:

f7fccadd1117ac3c390ed86fe8fba322

我这样的方式是最简单的,将一些actionIndex的方法都公开了,在实际应用中当然不可以这样。不过我这里是测试,当然是无所谓的

访问http://localhost/project/test/ (project是我的项目名称,test是controller, index是action,由于默认action是index,所以我省略了)

浏览器中返回了:

Fa4{s11"actionIndex"s11"afterAction"s5"hello"s3"sum"}z

由此其实我们也可以基本确认有四个方法可以使用actionIndex,afterAction,hello,sum,这主要是因为我把当前类当成发布对象了。(不主张啊不主张)

4、继续下一步,

<?php
include("./protected/extensions/hprose/hproseHttpClient.php");
$client = new HproseHttpClient("http://localhost/project/test");
$result = $client->sum(1,2,3,4,5);
print_r($result);

OK,浏览器输出了15,就这样完成了一个简单的HPROSE应用。

当然我这样的方式太简单了,文档在这里有下载,我就不再画蛇添足的提供了:http://www.hprose.com/documents.php。

因为只是简单的的一些应用,暂时也看不到hprose的性能比phprpc提升了多少。

---------------备注

由于Yii对于大小写敏感,因此在new HproseHttpServer();的时候,Hprose的H不能大写,否则,它会自动寻找HproseHttpServer.php,但由于PHP的hprose的文件中首字母都是小写。因此在new的时候就需要:new hproseHttpServer();

关于SOAP的几篇文章

关于SOAP的几篇文章

PHP操作soap我总觉得是一件非常痛苦的事情,但没有办法,现在很多功能都是基于WebService的,比如那个amazon的,但其实很多公司都也还是提供了restful之类的接口,使得PHP与其他系统的数据交换比较方便。但让人痛苦的,有时候,你PHP不得不充当soapServer,这时候,怎么做呢?zendstudio可以根据你的函数和类,帮你生成wsdl,但大多数情况下,你没有直接生成的手段,怎么办?官方的soapServer功能也太少了一点。你是否还准备用nuSoap来充当server呢?

搜集了一些资料,用来方便的协助你生成soap接口。如果只是自己的内部调用,可以尝试用phprpc或者它的升级版hprose进行尝试。

1、利用NuSOAP发布wsdl。这是PHP5之前的做法了,因为在PHP5之后,直接有soap库支持,如何发布wsdl,请看:http://hi.baidu.com/arlon/blog/item/d8267d1e6ca4adf01ad576cc.html,然而这个网址打开是白屏的,内容可以稍看这里:

2.4.1 创建支持 WSDL 的 WEB 服务
为了实现 WEB 服务程序对 WSDL 的支持,需要使用 soap_server 的 configureWSDL 方法,并且在调用 soap_server 的 register 方法注册 WEB 服务程序时,需要提供更详细的参数。看下面的代码,代码的文件名是 “/nusoap/nusoap_server3.php”。

<?php
require_once("lib/nusoap.php");

function concatenate($str1,$str2) {
if (is_string($str1) && is_string($str2))
return $str1 . $str2;
else
return new soap_fault(' 客户端 ','','concatenate 函数的参数应该是两个字符串 ');
}

$soap = new soap_server;
$soap->configureWSDL('concatenate'); // 初始化对 WSDL 的支持

// 注册服务
$soap->register('concatenate',
array("str1"=>"xsd:string","str2"=>"xsd:string"), // 输入参数的定义
array("return"=>"xsd:string") // 返回参数的定义
);

$HTTP_RAW_POST_DATA = isset($HTTP_RAW_POST_DATA) ? $HTTP_RAW_POST_DATA : '';
$soap->service($HTTP_RAW_POST_DATA);
?>
现在打开浏览器,访问刚才建立的文件,http://127.0.0.1/nusoap/nusoap_server3.php,结果如下:

concatenate
View the WSDL for the service. Click on an operation name to view it's details.

concatenate
点击函数名称concatenate,可以看到对函数的描述。点击"WSDL",或者访问WEB服务文件,并在后面加上查询字符串"?wsdl"(http://127.0.0.1/nusoap/nusoap_server3.php?wsdl),可以得到WEB服务的WSDL内容。

2.4.2 通过 WSDL 调用 WEB 服务
通过 WSDL 调用 WEB 服务,与不通过 WSDL 调用 WEB 服务,程序的结构大体相同。区别在于,通过 WSDL 调用 WEB 服务,初始化 soapclient 类时,传入两个参数到 soapclient 的构造函数,第一个参数是 WSDL 文件的地址,第二个参数指定是否使用 WSDL ,指定为 true 即可。看下面的代码,代码的文件名是 “ /nusoap/nusoap_client3.php ”

<?php
require_once("lib/nusoap.php");

$client = new soapclient('http://127.0.0.1/nusoap/nusoap_server3.php?wsdl',true);
$parameters=array(' 字符串 1',' 字符串 2');

$str=$client->call('concatenate',$parameters);
if (!$err=$client->getError()) {
echo " 程序返回 :",$str;
} else {
echo " 错误 :",$err;
}
?>
2.4.3 代理的使用
NuSOAP 提供代理的方法调用远程 WEB 服务。这种方法,在客户端程序里面创建一个远程服务的代理对象,通过代理直接调用远程的 WEB 服务,而不需要通过 soalclient 类的 call 方法。看下面的代码。

<?php
require_once("lib/nusoap.php");

$client = new soapclient('http://127.0.0.1/nusoap/nusoap_server3.php?wsdl',true);
$proxy=$client -> getProxy(); // 创建代理对象 (soap_proxy 类 )

$str=$proxy->concatenate(" 参数 1"," 参数 2"); // 直接调用 WEB 服务
if (!$err=$proxy->getError()) {
echo " 程序返回 :",$str;
} else {
echo " 错误 :",$err;
}
?>

2、利用PHP5自带的soapServer,在手册上,关于如何创建,写了很多例子,就象:

<?php
$server = new SoapServer("some.wsdl");
$server = new SoapServer("some.wsdl", array('soap_version' => SOAP_1_2));
$server = new SoapServer("some.wsdl", array('actor' => "http://example.org/ts-tests/C"));
$server = new SoapServer("some.wsdl", array('encoding'=>'ISO-8859-1'));
$server = new SoapServer(null, array('uri' => "http://test-uri/"));

class MyBook {
public $title;
public $author;
}

$server = new SoapServer("books.wsdl", array('classmap' => array('book' => "MyBook")));
?>

反正,我是觉得很痛苦,不过所幸现在的IDE都支持了直接发布wsdl文件,netbeans可以,zendstudio也可以。所以,也就方便了开发

3、利用开源组件,比如:webservice helper,http://www.jool.nl/new/1,webservice_helper.html,虽然它也是其于soapServer,但是集成的一些代码可以让你少走很多弯路。

比如,它默认就自带了一个contactManager的发布,具体的一些配置,可以看config.php,当然你也可以参考它的一些类,也充实你自己的类库(本来官网有教程的,可能是因为时间太久远了,该教程已经跳到ipublisher的教程上去了)

4、利用框架实现webService。在这里,估计又有很多分支了,比如zend framework,比如xxx和xxxx等,我由于最近在用yii,所以就看了yii的一个小小的实现

介绍页在这里:http://www.yiiframework.com/doc/guide/1.0/zh_cn/topics.webservice

看它的实现是非常简单,在Controller里增加一个转换wsdl的Action,然后,在要提供的方法上面用phpdoc来进行注释。定义传入参数的数据类型等

  • str/string: 对应 xsd:string;
  • int/integer: 对应 xsd:int;
  • float/double: 对应 xsd:float;
  • bool/boolean: 对应 xsd:boolean;
  • date: 对应 xsd:date;
  • time: 对应 xsd:time;
  • datetime: 对应 xsd:dateTime;
  • array: 对应 xsd:string;
  • object: 对应 xsd:struct;
  • mixed: 对应 xsd:anyType.

不过我也确实没有过多的细看,没仔细看它对于AUTH验证支持怎么样(第三点里介绍的工具是有验证的,而且就设在config.php里,非常方便)

好了,我就针对现在的soap server的建立,介绍了四种方法,事实上,我到现在为止是一种都没有用过,nusoap也就用过客户端,那也是几年前的事情了,soapClient也是,在构建soapHeader的时候也走过很多弯路。第三步介绍的工具,我也只是下载了看看源码,第四步我是看了看手册。只是先集中一下,以后总会用到而已。
虽然说,PHPRPC和hprose 在andot他们介绍来说,开发速度和处理上,都有较为明显的提高,但如果想做一个公用的web service,那还是用大家都能接受的方法吧。
如果是自己的项目,那可能就会用phprpc或者hprose来了。hprose测试版用过,感觉还是不错的。phprpc,我也做了一个sae平台的移植版,目前也能够正常的使用。。在这里也有个简单的测试:http://nsblog.sinaapp.com/。有兴趣的朋友也可以去看看的。

测试phprpc_client for SAE

测试phprpc_client for SAE

为了测试phprpc_client for SAE,到小菜鸟的app网站上把他的API全部复制到SAE的空间里,做了一点测试。有不少功能呢。每个例子最后我都用highlight_file把当前文件全部打印出来。可以,写的时候就可以做参考了。

事实上也没有什么 好参考的,小菜鸟的网上有的是代码,还有演示,我这里只是仅仅作了COPY而己。

对于最后的页面显示时间,这个就涉及到网络关系了,和实际执行时间并没有太大的联系,纯粹一看。

很多例子都在:

小菜鸟的APP网站是:MYWS,对了。小菜鸟还做了一个Ecshop的皮肤,仿凡客,也不错,演示在:http://shop.17kaixin8.com/,如果觉得好,也可以向他购买哦。

基本实现 phprpc_client For SAE

基本实现 phprpc_client For SAE

自从申请了SAE后,不知道用来干什么 ,于是就有了利用SAE监控网站 ,后来我想应该把PHPRPC移过去吧,于是就开始了简单的移植。由于SAE的【http://wiki.sae.sina.com.cn/doku.php?id=sae%E5%BC%80%E5%8F%91%E8%80%85%E6%89%8B%E5%86%8C#%E8%BF%90%E8%A1%8C%E7%8E%AF%E5%A2%83%E7%AE%80%E4%BB%8B】,所以在移植前要注意,比如没有ini_get,ini_set之类的。而且sae取消了fsockopen远程地址,是改用curl的。因此对于这些也需要改的

经过一个下午的折腾,基本上完成了移植,可以查看:http://nsblog.sinaapp.com/test.php,这是客户端。http://nsblog.sinaapp.com/是服务端。服务端公布两个简单的方法:trim,hello。

大家可以测试一下。(目前还没有测试proxy,加密等其他协议之类的。gzip可以用)

其他协议周一继续测试 ,等稍微稳定后,我会向andot提交代码。

使用PHPRPC与论坛同步登录退出

使用PHPRPC与论坛同步登录退出

很久以前就用过PHPRPC,几年没用了,虽然一直在关注着,最近尝试着他来做了一下DZ6.0论坛,把遇到的情况与大家分享一下

首先使用PHPRPC把服务器的一些信息传递给客户端,如cookie的一些设置还有最重要的auth_key,然而即使是这样,我最后也没有同步成功。

经过仔细检查,才发现原来是authcode函数所导致。因为authcode函数里使用了一个全局变量$discuz_auth_key,这个key是在使用common.inc.php的时候根据useragent加上一定的规范而生成的。我在传递的时候把这个变量传回给了客户端,但发现通过PHPRPC生成的key与直接使用浏览器打开生成的KEY不一样。导致最后登录所生成的COOKIE无法decode,最后根据这个生成key的规范,在客户端直接生成好发送给服务端覆盖掉全局变量,使得验证通过。

(写的有点乱,其实就是对于不是从数据库里读出来的全局变量,PHPRPC访问时与直接浏览器访问时所生成的数据不一样)

然后在登录的时候因为DZ还要判断SID,如果有SID了那肯定是无法同步登录(理由和上面一样,两边生成的SID会不一样),于是先清空SID,然后再登录,由服务端生成好SID再传回来,就OK了。。。

由于这次是加载common.inc.php进行处理的,所以很多变量会在系统加载的时候生成,但由于我采用了PHPRPC,在这一步完成后,我会尝试不再加载common.inc.php,这样也可以节约开销(在用户量不大的时候无所谓,但因为每次调用PHPRPC,可能会造成在线用户数加1 这个问题。)

逐步改进,oh yeah