RPC是Remote Procedure Call的缩写,翻译成中文就是远程过程调用,是一种在本地的机器上调用远端机器上的一个过程(方法)的技术,这个过程也被大家称为“分布式计算”,是为了提高各个分立机器的“互操作性”而发明出来的技术。
按照“数据即程序”的观点来看,RPC无非是借助一些通信手段来互相传递数据(信息),所也她也是“高”层次的通信手段,无非是这种通信手段看起来更像是“过程的调用”,因为她往往以一个“函数”的面目示人,从而掩盖了她交换信息的实质。
在各种RPC技术中,我想应该以Sun的RPC最为著名,比较流行的网络文件系统NFS就是建立在SUN RPC技术基础之上的。
XMLRPC, 顾名思义(我总是喜欢这样把问题简单化,因为一个比较好的名字往往能概括出一个东西的本质,如果某个名字让你摸不着头脑,我推荐你放弃它,因为那个发明这 个东西的人都不知道它的实质,所以你也就没有必要在其上浪费无谓的时间和精力。)就是应用了XML技术的RPC。那么什么是XML了?
XML和 RPC一样也是一个东西的缩写,这个东西就是eXtensible Markup Language,中文意思就是可扩展标记语言,标记语言就是那种用尖括号(<>)括来括去的那种语言,比如说HTML。XML的可扩展性也 体现在它只定义了语言的格式,而并没有定义过多的关键字,也就是通常所说的标记(Tag),所以用户可以自由地选择定义标记。它的这种自由和简单的语法规 则也使得它广为流传,被用来表示各种数据。熟悉Lisp语言(一种被称为“一大堆”括号的语言)的同学可能觉得XML和Lisp语言有些类似,不同的是 XML用尖括号替代了Lisp语言中的圆括号(())。事实就是他们都是那么相似,那么多语言似乎都是等价的,不同的只是那些应用语言的人。
XML在XMLRPC充当什么角色呢?
答 案就是“交换的数据格式”。在Sun RPC中,调用双方传递的数据是二进制的,而在XMLRPC中数据将是XML格式的。那么为什么用XML而不用二进制呢?我想一方面应该是为了兼容更多的 语言,因为这个世界上除了C/C++等编译语言,还有很多类似python,perl,javascript等的脚本语言(最近有些文章也称其为“动态语 言”,因为他们通常不需要自己管理内存),另一方面是为了隔离操作系统的差异,比如说Little Endian和Big Endian的差异等。基于种种原因,XMLRPC选择了XML这种中间语言作为其信息的格式,然后由各个语言负责将其转变成各自native(本土)的 数据类型。关于为了兼容各个语言所发明的中间语言还有IDL(Interface Definition Language:接口定义语言),它被用于CORBA接口的定义。
关于XMLRPC的更多信息请到它的 官方网站去学习,其中有XMLRPC的 规范(Specification),不过是相当得简单的,因为XMLRPC本身就特别的简单,不相信?好,那下面我就请大家和我一起来学习如何写一个加法的XMLRPC。
服务器端:
因为XMLRPC的消息是用标准的HTTP协议进行传递的,所以我们的服务端也采用运行在apache上的php来开发,作为必要条件,我们需要在我们的系统上安装上php语言的xmlrpc开发库。我选用 phpxmlrpc,因为php在很多情况下并不启用对XMLRPC的支持。下载之后,将其的lib目录拷贝出来并命名为libphpxmlrpc,下面书写我们的第一个XMLRPC实现:
file: xmlrpc_server.php
是不是很简单明了啊?通过上面的代码我想您肯定可以通过CPCS(Copy, Paste, Change, Save)的方法举一反三出更多的XMLRPC来。
客户端:
为 了测试我们的程序是否正确,需要写一个客户端来,用什么来写呢?或者是用什么写更方便呢?简单思考之后,python应该比较简单,简单的google了 一下,得知xmlrpc的实现已经被纳入官方python的支持之中,窃喜,通过CPCS方法很快就写出了客户端实现,如下:
File: xmlrpc_client.py
注:我开发的根目录为/home/xiaosuo/xmlrpc/所以网页的目录也就自然为http://127.0.0.1/~xiaosuo/xmlrpc/,以下相同。
测试:
Ok!一切顺利。
以下还有几个语言的实现版本请看客们自行分析,并通过CPCS方法学习使用:
使用phpxmlrpc的php版:
使用来自
xmlrpc-c的xmlrpc命令的shell版:
使用xmlrpc-c的C语言版:
使用Frontier库的Perl版本:
是不是开始感叹XMLRPC被支持的程度了,事实上远不止这些,更多的语言支持请到XMLRPC的官方网站的 实现列表里面去查看。
http://blog.chinaunix.net/u/5251/showart.php?id=188570
按照“数据即程序”的观点来看,RPC无非是借助一些通信手段来互相传递数据(信息),所也她也是“高”层次的通信手段,无非是这种通信手段看起来更像是“过程的调用”,因为她往往以一个“函数”的面目示人,从而掩盖了她交换信息的实质。
在各种RPC技术中,我想应该以Sun的RPC最为著名,比较流行的网络文件系统NFS就是建立在SUN RPC技术基础之上的。
XMLRPC, 顾名思义(我总是喜欢这样把问题简单化,因为一个比较好的名字往往能概括出一个东西的本质,如果某个名字让你摸不着头脑,我推荐你放弃它,因为那个发明这 个东西的人都不知道它的实质,所以你也就没有必要在其上浪费无谓的时间和精力。)就是应用了XML技术的RPC。那么什么是XML了?
XML和 RPC一样也是一个东西的缩写,这个东西就是eXtensible Markup Language,中文意思就是可扩展标记语言,标记语言就是那种用尖括号(<>)括来括去的那种语言,比如说HTML。XML的可扩展性也 体现在它只定义了语言的格式,而并没有定义过多的关键字,也就是通常所说的标记(Tag),所以用户可以自由地选择定义标记。它的这种自由和简单的语法规 则也使得它广为流传,被用来表示各种数据。熟悉Lisp语言(一种被称为“一大堆”括号的语言)的同学可能觉得XML和Lisp语言有些类似,不同的是 XML用尖括号替代了Lisp语言中的圆括号(())。事实就是他们都是那么相似,那么多语言似乎都是等价的,不同的只是那些应用语言的人。
XML在XMLRPC充当什么角色呢?
答 案就是“交换的数据格式”。在Sun RPC中,调用双方传递的数据是二进制的,而在XMLRPC中数据将是XML格式的。那么为什么用XML而不用二进制呢?我想一方面应该是为了兼容更多的 语言,因为这个世界上除了C/C++等编译语言,还有很多类似python,perl,javascript等的脚本语言(最近有些文章也称其为“动态语 言”,因为他们通常不需要自己管理内存),另一方面是为了隔离操作系统的差异,比如说Little Endian和Big Endian的差异等。基于种种原因,XMLRPC选择了XML这种中间语言作为其信息的格式,然后由各个语言负责将其转变成各自native(本土)的 数据类型。关于为了兼容各个语言所发明的中间语言还有IDL(Interface Definition Language:接口定义语言),它被用于CORBA接口的定义。
关于XMLRPC的更多信息请到它的 官方网站去学习,其中有XMLRPC的 规范(Specification),不过是相当得简单的,因为XMLRPC本身就特别的简单,不相信?好,那下面我就请大家和我一起来学习如何写一个加法的XMLRPC。
服务器端:
因为XMLRPC的消息是用标准的HTTP协议进行传递的,所以我们的服务端也采用运行在apache上的php来开发,作为必要条件,我们需要在我们的系统上安装上php语言的xmlrpc开发库。我选用 phpxmlrpc,因为php在很多情况下并不启用对XMLRPC的支持。下载之后,将其的lib目录拷贝出来并命名为libphpxmlrpc,下面书写我们的第一个XMLRPC实现:
file: xmlrpc_server.php
<?php include ("libphpxmlrpc/xmlrpc.inc"); include ("libphpxmlrpc/xmlrpcs.inc"); if ($_SERVER['REQUEST_METHOD'] != 'POST') exit(0); $add_sig = array(array($xmlrpcString, $xmlrpcInt, $xmlrpcInt)); $add_doc = "Add the two integer together"; function add($params) { global $xmlrpcerruser; $val = php_xmlrpc_decode($params); $ret = $val[0] + $val[1]; return new xmlrpcresp(new xmlrpcval($ret, "int")); } $server = new xmlrpc_server(array( "add" => array( "function" => "add", "signature" => $add_sig, "docstring" => $add_doc ))); ?> |
客户端:
为 了测试我们的程序是否正确,需要写一个客户端来,用什么来写呢?或者是用什么写更方便呢?简单思考之后,python应该比较简单,简单的google了 一下,得知xmlrpc的实现已经被纳入官方python的支持之中,窃喜,通过CPCS方法很快就写出了客户端实现,如下:
File: xmlrpc_client.py
#!/bin/env python from xmlrpclib import * import sys # xmlrpc add sample in python server = Server("http://127.0.0.1/~xiaosuo/xmlrpc/xmlrpc_server.php"); try: retval = server.add(12, 13) print retval except Error, v: print "Error", v |
测试:
xiaosuo@gentux xmlrpc $ ./xmlrpc_client.py 25 |
以下还有几个语言的实现版本请看客们自行分析,并通过CPCS方法学习使用:
使用phpxmlrpc的php版:
<?php include ("libphpxmlrpc/xmlrpc.inc"); include ("libphpxmlrpc/xmlrpcs.inc"); if (isset($_POST['var1']) && isset($_POST['var2'])) { $client = new xmlrpc_client("http://127.0.0.1/~xiaosuo/xmlrpc/xmlrpc_server.php"); $msg = new xmlrpcmsg("add", array( new xmlrpcval($_POST['var1'], "int"), new xmlrpcval($_POST['var2'], "int"))); $retval = &$client->send($msg); if ($retval->faultCode()) { print_r("An error occurred: "); print_r("Code: " . htmlspecialchars($retval->faultCode()) . " Reason: " . htmlspecialchars($retval->faultString())); } else { $sum = $retval->value()->scalarval(); } } ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/2000/REC-xhtml1-20000126/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>xmlrpc add sample in php</title> </head> <body> <form method="POST" <?php print_r('action="' . $_SERVER["PHP_SELF"] . '"'); ?> > <input type="text" name="var1" <?php print_r('value="' . $_POST['var1'] . '"'); ?> /> + <input type="text" name="var2" <?php print_r('value="' . $_POST['var2'] . '"'); ?> /> <input type="submit" value="="/> <input type="text" name="sum" <?php print_r('value="' . $sum . '"'); ?> /> </form> </body> </html> |
#!/bin/bash xmlrpc http://127.0.0.1/~xiaosuo/xmlrpc/xmlrpc_server.php add i/12 i/13 |
/* * Compile method: * gcc -o xmlrpc_client.out `xmlrpc-c-config --libs --cflags` xmlrpc_client.c -lxmlrpc_client */ #include <stdlib.h> #include <stdio.h> #include <xmlrpc.h> #include <xmlrpc_client.h> #define NAME "XML-RPC C Test Client" #define VERSION "1.0" #define die_if_fault_occurred(x) / do { / if ((x)->fault_occurred) / abort(); / } while(0) int main(int const argc, const char ** const argv) { xmlrpc_env env; xmlrpc_value * resultP; int sum; char *const url = "http://127.0.0.1/~xiaosuo/xmlrpc/xmlrpc_server.php"; char *const methodName = "add"; /* Initialize our error-handling environment. */ xmlrpc_env_init(&env); /* Start up our XML-RPC client library. */ xmlrpc_client_init2(&env, XMLRPC_CLIENT_NO_FLAGS, NAME, VERSION, NULL, 0); die_if_fault_occurred(&env); /* Make the remote procedure call */ resultP = xmlrpc_client_call(&env, url, methodName, "(ii)", (xmlrpc_int32) 12, (xmlrpc_int32) 13); die_if_fault_occurred(&env); /* Get our state name and print it out. */ xmlrpc_parse_value(&env, resultP, "i", &sum); die_if_fault_occurred(&env); printf("The sum is %d/n", sum); /* Dispose of our result value. */ xmlrpc_DECREF(resultP); /* Clean up our error-handling environment. */ xmlrpc_env_clean(&env); /* Shutdown our XML-RPC client library. */ xmlrpc_client_cleanup(); return 0; } |
#!/bin/env perl # use strict; use warnings; use Frontier::Client; my $server = Frontier::Client->new( url => "http://127.0.0.1/~xiaosuo/xmlrpc/xmlrpc_server.php"); my $sum = $server->call("add", (12, 13)); print $sum . "/n"; |
是不是开始感叹XMLRPC被支持的程度了,事实上远不止这些,更多的语言支持请到XMLRPC的官方网站的 实现列表里面去查看。
http://blog.chinaunix.net/u/5251/showart.php?id=188570