浏览模式: 标准 | 列表
3月
14

Nusoap vs PHPRPC for PHP

因为看到有人问 Nusoap 和 PHPRPC 的比较,为了让大家能够更清楚地了解 Nusoap 和 PHPRPC 的关系,所以在这里做一个简要的说明性介绍,所写的内容也不是面面俱到的,只写了一些主要的比较。更多细节的比较大家可以在使用中自己来对比。

Nusoap 是一个用于 PHP 的 Web Service 实现。PHP 版本的 PHPRPC 协议实现跟 Nusoap 是一个级别的东西。但是 PHPRPC 协议是跟 Web Service 一个级别的东西,所以下面我们来把 Nusoap 实现跟 PHP 版本的 PHPRPC 协议实现进行比较,把 Web Service 和 PHPRPC 协议进行比较。

1、协议比较:

相同之处:

这两个协议都是基于 HTTP 协议的,都可以使用 POST 方法提交请求。

主要不同之处:

(1) 请求:WebService 虽然也支持 GET 方式提交请求,但是一般不常用,常用的方式是利用 POST 方法提交 SOAP 格式的请求。而 PHPRPC 支持 GET 和 POST 两种方式来提交请求,请求格式是最常见的 application/x-www-form-urlencoded 格式,这对于实现一个浏览器客户端来说更加容易。

(2) 响应:WebService 返回的响应是 SOAP 格式的数据,对于浏览器客户端来说,只有利用 XMLHttpRequest 才能够对其进行处理,因为 XMLHttpRequest 收到跨域调用的限制,因此 WebService 的浏览器客户端无法做到跨域调用服务。PHPRPC 的响应格式是兼容于 JavaScript 格式的纯文本,因此返回的响应可以直接作为脚本执行,因此实现浏览器客户端可以完全不依赖于 XMLHttpRequest,利用纯 JavaScript 即可实现一个浏览器客户端,而浏览器允许跨域下载并执行脚本,因此 PHPRPC 的浏览器客户端可以做到跨域调用。

(3) 数据交换格式:WebService 中所使用的 SOAP 格式是基于 XML 语言定义的,XML 语言是纯文本的,因为其中的某些位置可以增加或删除一些空白(空格、制表符、回车或换行)而不影响其所表示的内容,因此其格式可以整理成便于人来阅读的,但也由于这点的灵活性,对于机器处理来说效率偏低。而 PHPRPC 的数据交换格式是 PHP 序列化格式,PHP 序列化格式可以算是半纯文本的,因为其数据的表示格式也是采用人类可读的方式表示的,但其中任何位置都不可以插入多于的空白,它对机器的可读性作了很好的支持,不但提供了有效的分隔符,并且提供了字符串长度、数组元素个数、对象成员个数等信息,所以更有利于机器高速处理。因为协议本质上是机机语言,而不是计算机程序设计语言,计算机程序设计语言是人机语言,它应该更偏重于人类可读性,而机机语言应该更重视机器可读性。因此可以说 PHP 序列化格式在人类可读性和机器可读性之间做到了非常好的平衡。

(4) 带宽占用:WebService 是重量级的 Web 服务,其数据格式冗长拖沓,占用网络带宽高。PHPRPC 是轻量级的 Web 服务,其数据格式简单紧凑,占用网络带宽低。注意,这里所说到重量级和轻量级是指网络带宽占用,而不是指其提供服务的能力,PHPRPC 所提供的服务能力绝不逊色于 WebService,甚至在很多地方优于 WebService。打个比方说:WebService 就像是 OSI 的 7 层网络模型,看似完美,但实现复杂,使用困难。而 PHPRPC 则像是简化了的 TCP/IP 的 5 层网络模型,实现高效,使用方便。

2、然后我们再来比较 Nusoap 和 PHP 版本的 PHPRPC 协议实现:

相同之处是都用于 PHP。

不同之处主要在于易用性上,Nusoap 虽然在易用性上做的还算不错,但是跟 PHP 版本的 PHPRPC 协议实现来比较就差太远了。例如,利用 Nusoap 发布的服务函数需要单独编写,而不能使用跟本地函数同样的方式进行编写,更无法使用 PHP 中内置扩展的函数,而 PHPRPC 所发布的函数跟本地函数完全一样,甚至包括 PHP 内置扩展的函数也可以直接发布。要用 Nusoap 发布一个 wsdl,需要为每一个发布的过程的名称、参数名、参数类型、返回值类型、名空间、动作、样式、文档等内容进行定义。而要发布一个 PHPRPC 服务,只需要告诉服务器要发布的那个函数(也可以是对象方法或类方法)的名字(还可以给出别名)即可。而不需要给出参数名、参数类型、返回值类型等信息。因此对于变长参数,可变类型参数的支持更好。在 PHPRPC 客户端的使用上,也是同样的方便,可以直接以远程函数名命名的本地 PHPRPC 客户端的方法来调用远程函数,而 Nusoap 相对来说比较麻烦一些。PHPRPC 还有一个很大的优势在于,它可以让你很轻松的以安全加密传输的方式来进行远程调用,这一点 Nusoap 是做不到的。

» 阅读全文

Beta 3 Update:

修改了对 Session 的处理方法,在同一会话中可以支持多个客户端进行安全加密传输。
重新编写的纯 PHP 实现的大整数运算库,比原来的版本更加高效。
由于 gmp 在处理大整数运算时速度最快,对密钥交换时所使用的大整数运算的扩展设置为 gmp 优先,其次是 big_int、bcmath 扩展,最后是纯 PHP 实现的大整数运算库。

Beta 2 Update:

更加完善了对客户端发起的 Session 处理。
增加了对 Fatal 和 Compile 错误重定向到客户端的支持。
修正了原来对 PHP 反序列化未定义类时的错误处理。

Beta 1 Update:

实现了 PHPRPC 3.0 协议升级描述中的内容。
实现了 PHPRPC 3.0 for PHP Server API Draft 中的所有接口。
增加了对禁用 Cookie 的客户端的支持(3.0 客户端支持该功能)。
支持 PHP 4.2+ 和 PHP 5+。
增加对没有 bcmath、gmp 和 big_int 扩展的支持。
增加了对 PHP 5 的异常处理的支持。
增加了当客户端传递一个服务器端未定义的类的对象时,服务器端自动定义该类的支持。
与 PHPRPC 2.1、2.0、1.1 的客户端相兼容。

Download: phprpc_3.0_php_server_beta_3.zip

该版本已过期。

» 阅读全文

Server API:

constructor PHPRPC_Server();

Create the PHPRPC Server object.

Add(String funcname, Object obj);
Add(String funcname, Object obj, String alias);
Add(String[] funcnames, Object obj);
Add(String[] funcnames, Object obj, String[] aliases);
 
Add(String funcname, Type type);
Add(String funcname, Type type, String alias);
Add(String[] funcnames, Type type);
Add(String[] funcnames, Type type, String[] aliases);

Add instance methods or static methods to the server. The methods can have aliases. This method must be called before start().

SetCharset(String charset);
SetCharset(Encoding encoding);

Set the charset of the server. This method must be called before start();

SetDebugMode(Boolean debug);

Set the debug mode of the server. This method must be called before start();

Start();

Start the PHPRPC server. This method usually be called at the end of page. This method can NOT be called twice or more in one page.

Client API:

constructor PHPRPC_Client();
constructor PHPRPC_Client(String serverURL);
constructor PHPRPC_Client.create();
constructor PHPRPC_Client.create(String serverURL);

Create PHPRPC Client object. The serverURL supports using username and password for the HTTP Basic Authorization, but it is NOT recommend. To use create method create PHPRPC Client object in VBScript.

SetProxy(String address);
SetProxy(String host, String port);
SetProxy(String host, String port, String username, String password);

Set the proxy server for the transfer. The address supports using username and password for the HTTP Basic Authorization, but it is NOT recommend. You can set the address to null to cancel the proxy server.

UseService(String serverURL);
UseService(String serverURL, String username, String password);

Set the URL of the PHPRPC Server. The serverURL supports using username and password for the HTTP Basic Authorization, but it is NOT recommend. You’d better to set username and password alone.

boolean SetKeyLength(int keyLength);

Set the key length for the key exchange. This method will return false when the key exchange already to be done.

int GetKeyLength();

Get the key length. This method will return actual value when the key exchange being done. Otherwise, you will get the default length or which length you set.

SetEncryptMode(int encryptMode);

Set the encrypt mode. 0 denotes no encrypting any data. 1 denotes encrypting arguments in the transfer. 2 denotes encrypting arguments and result. 3 denotes encrypting arguments, result and output of the server console.

Invoke(String function, param Object[] args);
Invoke(String function, ref Object[] args, bool byRef);

Invoke the server function with the function name and arguments array. if you want to transfer the arguments by reference, set byRef to be true.

String GetOutput();

Get the output of the server console after invoke the server function.

PHPRPC_Error GetWarning();

Get the warning of the server function after invoke the server function.

IWebProxy Proxy;

You can use this property to set the Proxy directly.

ICredentials Credentials;

You can use this property to set the Authorization directly.

» 阅读全文

在最新发布的 PHPRPC 2.1-20060810 版本中,包含了 PHPRPC for Java 版本。

PHPRPC for Java 不但可以使用 Servlet 发布服务,还可以简单的使用 JSP 来发布服务,并且可以直接发布 Java 内置类的方法。它支持在 JavaScript 中以异步远程调用方式来调用服务器端到过程(就像 DWR),可以更轻松的实现 Ajax 编程,另外,PHPRPC 的 JavaScript 在无需服务器代理的情况下就可以实现跨域调用,这是 DWR 所不能及的。PHPRPC 还支持在其它语言中(如 PHP、ASP、.NET 和 Java 本身)来远程调用 PHPRPC for Java 服务器上的过程。当然 PHPRPC for Java 的客户端也可以调用任何语言实现的 PHPRPC 服务器上的过程。它不但支持简单的整数、实数、字符串等基本类型,而且支持数组和所有 Java 中可以序列化的对象的传递。另外,PHPRPC for Java 最重要的一点是,它支持加密传输,让你无需部署 https 也可以安全传输数据,轻而易举的就可以实现 Ajax 安全编程了!

特点先介绍这么多,其实还有好多,就不说了,先说安装吧。

安装:

安装很简单,首先当然是下载咯,http://www.coolcode.cn/show-206-1.html 这里提供了3个下载地址,其中 CoolCode.CN 下载的始终是最新版本,Live-Share 上是特定的版本,Sf.net 上有所有发布的版本,不过只有 2.1-20060810 及其之后的版本才含有 PHPRPC for Java,所以,下载最新版本就可以了。

下载之后解压缩,你会发现所有语言的版本都有,并且按目录存放的,如果要用它作 Java 的 Ajax 编程,只需要 Java 版本和 js 版本就可以了。

首先要编译 Java 版本,这里提供了两种编译方式,一种是直接使用 JDK 编译,另一种是用 ant 编译,这两种编译方式都很简单,如果没有安装 ant,但是配置好了 JDK 的运行环境的话,直接进入 java 目录,键入 make 就可以编译完成了,不过这种方式只能在 Windows 下编译,因为没有提供 Linux 版本的 shell 脚本。如果安装了 ant 的话,就用 ant 方式编译,从命令行窗口进入 java 目录,键入 ant 就编译完成了,编译之后就会生成一个 phprpc.jar 的包,这种方式生成的 jar 包比较小,在各种系统下都可以运行,不过需要安装 ant,但我想用 Java 开发程序的同志应该都会用 ant 的吧。

OK,现在有了 phprpc.jar,我们就可以用它来做点东西了。

使用:

先说如何建立一个 JSP 的 PHPRPC 服务器。

首先在 Tomcat(或者其它 J2EE 服务器) 的发布目录下,建立一个 WEB-INF 目录,在下面再建立一个 lib 目录,把 phprpc.jar 放在 lib 目录中就可以了。然后在发布目录下建立你要发布服务的 JSP 程序,文件名当然是任意的,这里我们就叫 server.jsp 吧:

<%@ page import="java.lang.*" %>
<%@
page import="org.phprpc.*" %>
<%
PHPRPCServer phprpc_server = new PHPRPCServer(request, response, session);
phprpc_server.add("min", Math.class);
phprpc_server.add(new String[] { "sin", "cos" }, Math.class);
phprpc_server.start();
%>

就这么简单,这样就可以通过 server.jsp 来把 java.lang.Math 类的 min,sin,cos 方法发布给客户端调用了。

如果你在浏览器里键入:http://localhost:8080/server.jsp ,回车之后看到:

phprpc_functions="YTozOntpOjA7czozOiJtaW4iO2k6MTtzOjM6InNpbiI7aToyO3M6MzoiY29zIjt9";

的话,就表示成功了。

下面我们来看一下如何在 html 中用 js 调用这个服务。

首先把 js\compress\full 目录下的 phprpc_client.js 包含到你的 html 页面里来,这个压缩版本已经包含了所有的依赖程序,所以,你可以单独把它复制到任何目录下使用。

下面来建立一个 Html 页面试试吧:

<html>
<head>
<script type="text/javascript" src="phprpc_client.js"></script>
</head>
<body>
 
min(
<input id="a" type="text" />, <input id="b" type="text" />) <input id="minbtn" type="button" value="=" /> <input id="c" type="text" />
 
<script type="text/javascript">
var a = document.getElementById("a");
var b = document.getElementById("b");
var c = document.getElementById("c");
 
phprpc_client.create('rpc_client');
 
rpc_client.use_service("http://localhost:8080/server.jsp");
 
document.getElementById("minbtn").onclick= function() {
    if (rpc_client.ready) {
        c.value = "loading...";
        rpc_client.min(Number(a.value), Number(b.value), function (result) {
            c.value = result;
        });
    }
    else {
        alert("RPC not ready, wait a moment, please!");
    }
}
</script>
</body>
</html>

OK,打开试试吧,这个就可以调用服务器端的 min 函数来进行计算了。

» 阅读全文

经过了近一个月的努力开发与严格测试,PHPRPC_2.1-20060810 版终于发布了!

该版本最重要的更新是增加了 PHPRPC for Java 服务器和客户端。另外,修正了早期版本中的许多小问题,并进行了代码优化,剔出了过时的文件,更改了一些目录结构,去掉了内置的文档(以后会在 http://www.phprpc.org 上提供在线版本的文档)。下面是一些主要的更新说明:

修正了 XXTEA.cs 中当解密数据不对时造成的内存溢出错误(其他语言版本也作了修正)。
修正了 PHPSerializer.cs 中使用双字节编码字符集(例如 UTF16)时不能正确序列化的问题。
增加了对 NAN 序列化和反序列化(JavaScript,C# 和 Java 版本)。
移除了过时的 phprpc_ajax_client 和 phprpc_js_client。
将 php4_rpc_client.php 和 php5_rpc_client.php 合并入 phprpc_client.php。
修正了 PHPRPC for .NET 服务器端输出捕获的错误。
修正了 PHPRPC for .NET 客户端处理输出捕获的错误。
优化了 PHPRPC for .NET 客户端的代码。
修正了 PHPRPC for .NET 客户端代理设置后不能重置的问题。
为 PHPRPC for .NET 客户端增加了 Credentials 属性。
将 PHPRPC for PHP 转移到 php 目录下(移除了原来的 include 目录)。
修正了 PHPRPC for PHP 客户端引用参数处理不当的小问题。
修正了 PHPRPC for PHP 服务器端错误处理的一个小问题。
取消了内置文档。
增加了 LICENSE,README,INSTALL 和 AUTHORS 文件。
增加了 PHPRPC for Java 服务器和客户端。

下载:

» 阅读全文