XML-RPC HOWTO Eric Kidd Source Builders eric.kidd@pobox.com And Other Contributors ì{_ê - ú{ê|ó hng@ps.ksky.ne.jp Copyright (C) 2001 by Eric Kidd 0.8.0, 2001-04-12 Revision History Revision 0.8.0 2001-04-12 Updated section on common interfaces. Added pointer to XML-RPC.Net information. Revision 0.7.0 2001-04-03 Added section on C++ proxy classes. Revision 0.6.0 2001-02-02 Added sections on Ruby, K and common interfaces. Revision 0.5.0 2001-01-23 Initial version. lXȾêÅNCAg¨æÑT[oðÀ·é½ßÌ XML-RPC Ìgpû@ ðq×Ü·BáèÌvOÍ Perl, Python, C, C++, Java, PHP ¨æѼ ̾êŦµÄ¢Ü·BZope â KDE 2.0 É¢ÄàµÁĢܷBXML-RPC ÌT|[gÍ·×ÄÌIy[eBOVXeÅpÅ«Ü·B ªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªª Table of Contents 1. Legal Notice 2. XML-RPC ÆÍH 2.1. ÇÌæ¤É®ì·éÌ© 2.2. T|[g³êéf[^ÌíÊ 2.3. XML-RPC Ìðj 3. XML-RPC μÌvgR 3.1. XML-RPC Î CORBA 3.2. XML-RPC Î DCOM 3.3. XML-RPC Î SOAP 4. êÊIÈ XML-RPC C^[tF[X 4.1. CgXyNV - T[oÌ API ð@èo· 4.2. Boxcarring - ¯É¡Ìvðé 5. API Ìá - sumAndDifference 6. Perl ÅÌ XML-RPC Ìg¢û 6.1. Perl NCAg 6.2. Ƨ^ Perl T[o 6.3. CGI x[XÌ Perl T[o 7. Python ÅÌ XML-RPC Ìg¢û 7.1. Python NCAg 8. C ¨æÑ C++ ÅÌ XML-RPC Ìg¢û 8.1. C NCAg 8.2. C++ NCAg 8.3. ãÖNX (Proxy Class) ÅÌ C++ NCAg 8.4. CGI x[XÌ C T[o 9. Java ÅÌ XML-RPC Ìg¢û 9.1. Java NCAg 9.2. Ƨ^ Java T[o 10. PHP ÅÌ XML-RPC Ìg¢û 10.1. PHP NCAg 10.2. PHP T[o 11. Microsoft .NET ÅÌ XML-RPC Ìg¢û 12. Ruby ÅÌ XML-RPC Ìg¢û 12.1. Ruby NCAg 12.2. Ruby T[o 13. Æ©IȾêÅÌ XML-RPC Ìg¢û 13.1. K ÅÌ XML-RPC Ìg¢û 14. XML-RPC T|[gªgÝÜê½AvP[V 14.1. Zope 14.2. KDE 2.0 15. ±Ì¶É墀 15.1. ±Ì¶ÌVÅ 15.2. XML-RPC HOWTO ÌñeÒ 15.3. ¼ÌîñÌño 16. ú{êóÉ墀 1. Legal Notice Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License <http:// www.fsf.org/copyleft/fdl.html>, Version 1.1 or any later version published by the Free Software Foundation with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. You may obtain a copy of the GNU Free Documentation License from the Free Software Foundation by visiting their Web site <http://www.fsf.org/> or by writing to: Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. This manual contains short example programs ("the Software"). Permission is hereby granted, free of charge, to any person obtaining a copy of the Software, to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following condition: THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªª 2. XML-RPC ÆÍH XML-RPC <http://www.xmlrpc.com/> Í HTTP ãÅ[g豫ÄÑoµðs ¤½ßÌÈPÅèyÈû@Å·BPerl, Java, Python, C, C++, PHP â½Ì ¼ÌvO~O¾êÅgpÅ«Ü·BUnix Æ Windows, Macintosh ãÅ pÂ\Å·B Perl Å©ê½Z¢ XML-RPC NCAgð¦µÜ· (Ken MacLeod Ì Frontier::Client <http://bitsko.slc.ut.us/~ken/xml-rpc/> ðgpµÜ·) B use Frontier::Client; $server = Frontier::Client->new(url => 'http://betty.userland.com/RPC2'); $name = $server->call('examples.getStateName', 41); print "$name\n"; Às·éÆA±ÌvOÍ[gÌT[oÉÚ±µAB¼ð¾ÄA»ê ð\¦µÜ· (±ÌáÌBÔ 41 Í South Dakota Ì͸ŷ)B Python Å̯¶vOÅ· (±êÅÍ Fredrik Lundh Ì xmlrpclib <http://www.pythonware.com/products/xmlrpc/> ðg¢Ü·)B python> import xmlrpclib python> server = xmlrpclib.Server("http://betty.userland.com/RPC2") python> server.examples.getStateName(41) 'South Dakota' È~ÌÍÅÍAlXȾêÅ XML-RPC NCAg¨æÑT[oÌ«ûðw ÑÜ·B ªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªª 2.1. ÇÌæ¤É®ì·éÌ© XML-RPC Í Dave Winer Ìö®dl <http://www.xmlrpc.com/spec>ÅÚ×É à¾³êĢܷB»¡ª éÈçA¥ñ²ÉÈÁľ³¢BÈžð ȶŷB ÊM·éãÅAXML-RPC ÌlÍ XML ÉGR[h³êÜ· - sample.sumAndDifference 5 3 ãLÍç·Å·ªAÈPɳkÅ«Ü·BܽA\zÈãɬ¢Å· - Rick Blair ̪èÉæêÎAHannes Wallnfer Ì Java ÅÌÀðg¤Æ XML-RPC ÄÑoµÌÔÍ 3 ~bÅ·B ªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªª 2.2. T|[g³êéf[^ÌíÊ XML-RPC ÍȺÌf[^ÌíÊðT|[gµÜ·B int t 32 rbg® string ASCII ¶ñÅóoCgà³êÜ·B(ÀÛÉͽ³ñÌ XML-RPC Ì Àª Unicode ðT|[gµÄ¢Ü·BXML Ìî{@\É´ÓB) boolean ^©UÌÇ¿ç© double {¸x®¬_À (ÀÛÉ͢©ÌÀÅg¦È¢©àµêܹ ñ) dateTime.iso8601 útÆBcOȪçAXML-RPC Í^C][ÌgpðÖ~µÄ¢é ÌÅA±êÍÙÆñÇðɧ¿Ü¹ñB base64 Cӷ̶ÌoCif[^ - ÊMã Base64 ðgpµÄGR[h³ê Ü·BÆÄàð§¿Ü· (¯êÇà¢Â©ÌÀÅÍ 0 oCgÌf[^ óMªs¦Ü¹ñ)B array lÌê³zñBÂXÌlÍÇñÈíÊÅà©Ü¢Ü¹ñ struct L[ÆlÌWÜèBL[ͶñÅ· - lÍÇñÈíÊÅà©Ü¢Ü¹ñ B ªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªª 2.3. XML-RPC Ìðj XML-RPC ÍAæs·éñÂÌvgR©ç zð¾Ä¢Ü·B»ÌêÂÍA anonymous RPC Å èA±êÍ Dave Winer ÉæèÝv³êAßÉ DaveNet ÅÌGbZC <http://davenet.userland.com/1998/02/27/rpcOverHttpViaXml> ƵÄ\³ê½àÌÅ· (XML-RPC T[oª /RPC2 ºÉCXg[³êé ±Æª½¢Ìͱ̽ßÅ·)Bà¤êÂÌAæèdvÈ zÍASOAP vg RÌúhtgÉæéàÌÅ·B æèÚµ¢ XML-RPC Ìðj <http://www.xmlrpc.com/stories/ storyReader$555>Æ¢¤¶ð Dave Winer ªñµÄêĢܷB±Ì¶ ÅÍAXML-RPC Æ SOAP ÆÌÖWÉ¢ÄàླêĢܷB ªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªª 3. XML-RPC μÌvgR [g豫ÄÑoµÍ XML-RPC ªBêÌû@ÅÍ èܹñBlCÌ é ¼ÌvgRÉÍ CORBA, DCOM, SOAP ÈǪ èÜ·BevgRÉÍ· ÆZª èÜ·B ±ÌÍÅÌÓ©ÉÍA(ÒÌ) ¾ç©ÈΩàÜÜêĢܷBǤ©A»Ì _ðl¶µÄ¨Çݾ³¢B ªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªª 3.1. XML-RPC Î CORBA CORBA <http://www.corba.org/> ÍlCÌ évgRÅAªU^IuWF NgwüAvP[Vü¯É©êĢܷBêÊIÉ¡ÌwðÂG ^[vCYAvP[VÅgp³êÜ·BÅßÅÍAAvP[V ÔÊMpÉà Gnome <http://www.gnome.org/> vWFNgÉæÁÄIè³ êĢܷB CORBA ͽÌx_[â½³ñÌt[\tgEFAvWFNgÉæè AæT|[g³êĢܷBCORBA Í Java, C++ ƤܮìµA½Ì¼ ̾ê©çàpÂ\Å·B³çÉ CORBA ÍDê½ interface definition language (IDL) ðñµAÇÝâ·¢IuWFNgwü API ðè`Å«éæ ¤ÉµÜ·B cOȱÆÉACORBA ÍÆÄà¡GÅ·BwKÈüÍ}ùzÆÈÁÄ¢ÄAÀ ·éÌÉñíÈwÍðKvƵA©ÈèxÈNCAgðKvƵܷ BªU^EFuAvP[VæèàG^[vCYâfXNgbvAv P[VÉêÔKµÄ¢Ü·B ªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªª 3.2. XML-RPC Î DCOM DCOM <http://www.microsoft.com/com/tech/DCOM.asp> Í Microsoft Ì CORBA Éηé Microsoft ̦ŷB·ÅÉ COM R|[lgðgpµÄ¢Ä Microsoft ÈOÌVXeÆâèæè·éKvªÈ¯êÎAf°çµ¢àÌÅ ·B»¤ÅȯêÎA Üèðɧ½È¢Åµå¤B ªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªª 3.3. XML-RPC Î SOAP SOAP <http://www.w3.org/TR/SOAP/> ÍÆÄà XML-RPC ÉĢܷBXML ¶ ÌÜÜAHTTP ãÅ®ñµ½è±«ÄÑoµðs¤®ìàĢܷBcOÈ ªç SOAP ÍdlÌmèÉYñÅ¢éæ¤É©¦Ü·B SOAP ͳX UserLand, DevelopMentor, Microsoft ̤¯§ìÉæè쬳ê ܵ½BÅÌöÌ[XÍî{IÉl[Xy[XÆ·¢Gg¼ð  XML-RPC ŵ½Bµ©µ»Ìã SOAP Í W3C [LOO[vÉø« pªêܵ½B cOȱÆÉA[LOO[vÍ SOAPÉÆÄà½ÌsÂðÈ@\ÌÇÁ ðsÁĢܷB±Ì¶Ì·M_ÅASOAP Í XML XL[AG~ [ VAïÈ¡\¢Ì¨æÑzñA»µÄJX^^CvðT|[gµÄ ¢Ü·BÁ¦ÄA¢ÂàÌ SOAP ÌOdlÌÀàè`³êĢܷB î{IÉ XML-RPC ªD«Å é¯êÇàÁƽ³ñÌ@\ðÁ½vgR ð]ÞêASOAP 𲸷éÆ¢¢Åµå¤B :-) ªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªª 4. êÊIÈ XML-RPC C^[tF[X ¢Â©Ì XML-RPC T[oÍrgC\bhðñµÜ·B»êçÍ XML-RPC »ê©gÌàÌÅÍ èܹñªAÆÄàÖÈÇÁ@\Å·B ªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªª 4.1. CgXyNV - T[oÌ API ð@èo· Edd Dumbill ÍÌ\bhÌgÝðñÄ <http://xmlrpc.usefulinc.com/doc /reserved.html>µÜµ½B array system.listMethods () string system.methodHelp (string methodName) array system.methodSignature (string methodName) T[oª±êçÌ\bhðT|[g·éêA éhL e[Vð ó·é½ßÉT[oÖâ¢í¹ªÅ«Ü· - import xmlrpclib server = xmlrpclib.Server("http://xmlrpc-c.sourceforge.net/api/sample.php") for method in server.system.listMethods(): print method print server.system.methodHelp(method) print ±êçÌ\bhÍ PHP ¨æÑ CAMicrosoft .NET Å©ê½T[oÉæè T|[g³êĢܷBªIÈCgXyNVÌT|[gÍÅßÉÈ ÁÄ UserLand Frontier ÉàgÝÜêĢܷBPerl ¨æÑ Python, Java pÌCgXyNVÌT|[gÍ XML-RPC Hacks <http:// xmlrpc-c.sourceforge.net/hacks.php> Ìy[WÅüèÅ«Ü·BǤ¼A ¶ÈCgXyNVÌT|[gð¼Ì XML-RPC T[oÉÇÁµÄ¾ ³¢I lXÈNCAg¤Ìc[ (hL e[VAbp[¶¬) à XML-RPC Hacks Ìy[Wũ¯çêÜ·B ªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªª 4.2. Boxcarring - ¯É¡Ìvðé ½Ìt@NVR[ð·é XML-RPC NCAgð¢Ä¢éÈçA C^[lbgÌobN{[Ì[eV[ (Ò¿Ô) ªZ¢¨©°ÅA Ôª©È謢±ÆðCéàµêܹñB¢Â©ÌT[oÍÌ @\ðg¤±ÆÅ¡Ìvðê (batching) Å«Ü·B array system.multicall (array calls) ÇÁîñÍ system.multicall RFC <http://www.xmlrpc.com/discuss/ msgReader$1208> æè¾Ä¾³¢B »ÝA±Ì\bhÍ C ¨æÑ UserLand Frontier Å©ê½T[oÅT| [g³êĢܷBPython ¨æÑ Perl Å©ê½T[oÍ XML-RPC Hacks <http://xmlrpc-c.sourceforge.net/hacks.php> Ìy[WÉ évOð pÅ«Ü·B ªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªª 5. API Ìá - sumAndDifference XML-RPC Ìfð·é½ßÉAÂ\ÈÀè½Ì¾êÅȺɦµÜ·B struct sample.sumAndDifference (int x, int y) ±ÌÖÍø«ÆµÄñÂÌ®ðó¯æÁÄAñÂÌGgð XML-RPC <struct(\¢Ì)> ðߵܷ - sum ñÂÌ®Ìa difference ñÂ̷̮ ÀpIÈàÌÅÍ èܹñªA§hÈáèÉÈÁĢܷ :-) ±ÌÖ (â¼ÌàÌ) Í URL http://xmlrpc-c.sourceforge.net/api/ sample.php ðpµÄ¢Ü· (±Ì URL ÍuEUÅͽàÅ«¸AXML-RPC NCAgÅpÅ«Ü·)B ªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªª 6. Perl ÅÌ XML-RPC Ìg¢û Ken MacLeod Í Perl p XML-RPC ðÀµÄ¢Ü·BÞÌ Frontier::RPC W [ÍÞÌEFuTCg <http://bitsko.slc.ut.us/~ken/xml-rpc/>àµ Í CPAN <http://www.cpan.org/> ðʶÄüèÅ«Ü·B Frontier::RPC ðCXg[·éÉÍAWIÈâèûÅpbP[Wð_E [hµÄRpCµÜ· - bash$ gunzip -c Frontier-RPC-0.07b1.tar.gz | tar xvf - bash$ cd Frontier-RPC-0.07b1 bash$ perl Makefile.PL bash$ make bash$ make test bash$ su -c 'make install' (EBhE«â[g À̳¢êAí¸©ÉáÁ½èÆÈéÅµå¤ BÚ×Í Perl ̶ðQlɵľ³¢B) ªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªª 6.1. Perl NCAg ÌvOÍ Perl ©ç XML-RPC T[oÌR[Ìû@ð¦µÜ·B use Frontier::Client; # Make an object to represent the XML-RPC server. $server_url = 'http://xmlrpc-c.sourceforge.net/api/sample.php'; $server = Frontier::Client->new(url => $server_url); # Call the remote server and get our result. $result = $server->call('sample.sumAndDifference', 5, 3); $sum = $result->{'sum'}; $difference = $result->{'difference'}; print "Sum: $sum, Difference: $difference\n"; ªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªª 6.2. Ƨ^ Perl T[o The following program shows how to write an XML-RPC server in Perl: ÌvOÍ Perl ÅÌ XML-RPC T[oÌ«ûð¦µÜ·B use Frontier::Daemon; sub sumAndDifference { my ($x, $y) = @_; return {'sum' => $x + $y, 'difference' => $x - $y}; } # Call me as http://localhost:8080/RPC2 $methods = {'sample.sumAndDifference' => \&sumAndDifference}; Frontier::Daemon->new(LocalPort => 8080, methods => $methods) or die "Couldn't start HTTP server: $!"; ªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªª 6.3. CGI x[XÌ Perl T[o Frontier::RPC2 Í CGI x[XT[opÌT|[gÍ{õ¦çêĢܹñ Bµ©µåävAKvÈÙÆñÇÌ@\ÍpÓ³êĢܷB ÌvOR[hð sumAndDifference.cgi ƵÄAEFuT[oÌ cgi-bin fBNgÉÛ¶µÄ¾³¢ (Unix VXeãÅAchmod +x sumAndDifference.cgi Æü͵AÀs®«ð^¦éKvª éŵå¤)B #!/usr/bin/perl -w use strict; use Frontier::RPC2; sub sumAndDifference { my ($x, $y) = @_; return {'sum' => $x + $y, 'difference' => $x - $y}; } process_cgi_call({'sample.sumAndDifference' => \&sumAndDifference}); #========================================================================== # CGI Support #========================================================================== # Simple CGI support for Frontier::RPC2. You can copy this into your CGI # scripts verbatim, or you can package it into a library. # (Based on xmlrpc_cgi.c by Eric Kidd .) # Process a CGI call. sub process_cgi_call ($) { my ($methods) = @_; # Get our CGI request information. my $method = $ENV{'REQUEST_METHOD'}; my $type = $ENV{'CONTENT_TYPE'}; my $length = $ENV{'CONTENT_LENGTH'}; # Perform some sanity checks. http_error(405, "Method Not Allowed") unless $method eq "POST"; http_error(400, "Bad Request") unless $type eq "text/xml"; http_error(411, "Length Required") unless $length > 0; # Fetch our body. my $body; my $count = read STDIN, $body, $length; http_error(400, "Bad Request") unless $count == $length; # Serve our request. my $coder = Frontier::RPC2->new; send_xml($coder->serve($body, $methods)); } # Send an HTTP error and exit. sub http_error ($$) { my ($code, $message) = @_; print <<"EOD"; Status: $code $message Content-type: text/html $code $message Unexpected error processing XML-RPC request. EOD exit 0; } # Send an XML document (but don't exit). sub send_xml ($) { my ($xml_string) = @_; my $length = length($xml_string); print <<"EOD"; Status: 200 OK Content-type: text/xml EOD # We want precise control over whitespace here. print $xml_string; } Ƚ©gÌ CGI XNvgÉ[eBeB[`ðRs[µÄà©Ü¢ ܹñB ªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªª 7. Python ÅÌ XML-RPC Ìg¢û Fredrik Lundh ÍDê½Python p XML-RPC Cu <http:// www.pythonware.com/products/xmlrpc/>ðñµÄ¢Ü·B CXg[·é½ßÉAÅVÅð_E[hµÄ¾³¢B *.py t@C ðÂlÌ Python vOƵÄAÂlÌfBNgÉËÁñÅàA VXeÌ Python fBNgÉCXg[µÄà©Ü¢Ü¹ñB RedHat 6.2 Ì[UÍÌæ¤Éü͵ܷB bash$ mkdir xmlrpclib-0.9.8 bash$ cd xmlrpclib-0.9.8 bash$ unzip ../xmlrpc-0.9.8-990621.zip bash$ python python> import xmlrpclib python> import xmlrpcserver python> Control-D bash$ su -c 'cp *.py *.pyc /usr/lib/python1.5/' ãLÅÍAPython ÉñÂÌ *.py ðRpC³¹é½ßÉA»êçð import µÄ¢Ü·B¼ÌvbgtH[ÅÍ Python ̶ðQlÉµÄ ¾³¢B ³ç½Ì Python ÅÌáÉÖµÄÍAO'Reilly network Ì XML-RPC: It Works Both Ways <http://www.oreillynet.com/pub/a/python/2001/01/17/ xmlrpcserver.html> ÌLðÝľ³¢B ªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªª 7.1. Python NCAg ÌvOÍ Python ©ç XML-RPC T[oÌR[Ìû@ð¦µÜ·B import xmlrpclib # Create an object to represent our server. server_url = 'http://xmlrpc-c.sourceforge.net/api/sample.php'; server = xmlrpclib.Server(server_url); # Call the server and get our result. result = server.sample.sumAndDifference(5, 3) print "Sum:", result['sum'] print "Difference:", result['difference'] ªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªª 8. C ¨æÑ C++ ÅÌ XML-RPC Ìg¢û C/C++ p XML-RPC ÌRs[ð¾éÉÍAxmlrpc-c ÌEFuTCg <http:// xmlrpc-c.sourceforge.net>ð©Ä¾³¢B RPM `®Å·×ÄÌàÌð_E[h·é±ÆàA\[X©ç©ªÅ«ð \z·é±ÆàÅ«Ü·B ªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªª 8.1. C NCAg ÌvOR[hð getSumAndDifference.c ƵÄt@CÉÛ¶µÄ ¾³¢B #include #include #include #define NAME "XML-RPC getSumAndDifference C Client" #define VERSION "0.1" #define SERVER_URL "http://xmlrpc-c.sourceforge.net/api/sample.php" void die_if_fault_occurred (xmlrpc_env *env) { /* Check our error-handling environment for an XML-RPC fault. */ if (env->fault_occurred) { fprintf(stderr, "XML-RPC Fault: %s (%d)\n", env->fault_string, env->fault_code); exit(1); } } int main (int argc, char** argv) { xmlrpc_env env; xmlrpc_value *result; xmlrpc_int32 sum, difference; /* Start up our XML-RPC client library. */ xmlrpc_client_init(XMLRPC_CLIENT_NO_FLAGS, NAME, VERSION); xmlrpc_env_init(&env); /* Call our XML-RPC server. */ result = xmlrpc_client_call(&env, SERVER_URL, "sample.sumAndDifference", "(ii)", (xmlrpc_int32) 5, (xmlrpc_int32) 3); die_if_fault_occurred(&env); /* Parse our result value. */ xmlrpc_parse_value(&env, result, "{s:i,s:i,*}", "sum", &sum, "difference", &difference); die_if_fault_occurred(&env); /* Print out our sum and difference. */ printf("Sum: %d, Difference: %d\n", (int) sum, (int) difference); /* Dispose of our result value. */ xmlrpc_DECREF(result); /* Shutdown our XML-RPC client library. */ xmlrpc_env_clean(&env); xmlrpc_client_cleanup(); return 0; } RpC·é½ßÌüÍð¦µÜ· - bash$ CLIENT_CFLAGS=`xmlrpc-c-config libwww-client --cflags` bash$ CLIENT_LIBS=`xmlrpc-c-config libwww-client --libs` bash$ gcc $CLIENT_CFLAGS -o getSumAndDifference getSumAndDifference.c $CLIENT_LIBS ȽÌVXeÌ C RpC̼Oª gcc ÅÍÈ¢©àµêÈ¢ÌÅA ÀÛÌüÍÅÍ»êðã¦éKvª é©àµêܹñB ªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªª 8.2. C++ NCAg ÌvOR[hð getSumAndDifference2.cc ƵÄt@CÉÛ¶µÄ ¾³¢B #include #include #define NAME "XML-RPC getSumAndDifference C++ Client" #define VERSION "0.1" #define SERVER_URL "http://xmlrpc-c.sourceforge.net/api/sample.php" static void get_sum_and_difference () { // Build our parameter array. XmlRpcValue param_array = XmlRpcValue::makeArray(); param_array.arrayAppendItem(XmlRpcValue::makeInt(5)); param_array.arrayAppendItem(XmlRpcValue::makeInt(3)); // Create an object to resprent the server, and make our call. XmlRpcClient server (SERVER_URL); XmlRpcValue result = server.call("sample.sumAndDifference", param_array); // Extract the sum and difference from our struct. XmlRpcValue::int32 sum = result.structGetValue("sum").getInt(); XmlRpcValue::int32 diff = result.structGetValue("difference").getInt(); cout << "Sum: " << sum << ", Difference: " << diff << endl; } int main (int argc, char **argv) { // Start up our client library. XmlRpcClient::Initialize(NAME, VERSION); // Call our client routine, and watch out for faults. try { get_sum_and_difference(); } catch (XmlRpcFault& fault) { cerr << argv[0] << ": XML-RPC fault #" << fault.getFaultCode() << ": " << fault.getFaultString() << endl; XmlRpcClient::Terminate(); exit(1); } // Shut down our client library. XmlRpcClient::Terminate(); return 0; } RpC·é½ßÌüÍð¦µÜ· - bash$ CLIENT_CFLAGS=`xmlrpc-c-config c++ libwww-client --cflags` bash$ CLIENT_LIBS=`xmlrpc-c-config c++ libwww-client --libs` bash$ c++ $CLIENT_CFLAGS -o getSumAndDifference2 getSumAndDifference2.cc $CLIENT_LIBS ±ÌìÆ̽ßÉA©ÈèÅßÌ C++ RpCªKvÆÈèÜ·B ªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªª 8.3. ãÖNX (Proxy Class) ÅÌ C++ NCAg XML-RPC T[oªCgXyNV API ðT|[gµÄ¢éÈçA©®I É»ÌT[opÌ C++ ãÖNXð¶¬Å«Ü·BãÖNX𶬷é½ß ÉÍAÌR}hðü͵ĻÌoÍðt@CÉÛ¶µÄ¾³¢B bash$ xml-rpc-api2cpp \ > http://xmlrpc-c.sourceforge.net/api/sample.php sample SampleProxy ±êÍ sample ÅnÜé·×ÄÌ\bhpÌbp[ªÜÜêÄ¢é SampleProxy Ƽïçê½ãÖNX𶬵ܷB Ƚª]Þû@ű ÌNXðC³µÄà©Ü¢Ü¹ñB ªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªª 8.4. CGI x[XÌ C T[o ÌvOR[hð sumAndDifference.c ƵÄt@CÉÛ¶µÄ¾ ³¢B #include #include xmlrpc_value * sumAndDifference (xmlrpc_env *env, xmlrpc_value *param_array, void *user_data) { xmlrpc_int32 x, y; /* Parse our argument array. */ xmlrpc_parse_value(env, param_array, "(ii)", &x, &y); if (env->fault_occurred) return NULL; /* Return our result. */ return xmlrpc_build_value(env, "{s:i,s:i}", "sum", x + y, "difference", x - y); } int main (int argc, char **argv) { /* Set up our CGI library. */ xmlrpc_cgi_init(XMLRPC_CGI_NO_FLAGS); /* Install our only method (with a method signature and a help string). */ xmlrpc_cgi_add_method_w_doc("sample.sumAndDifference", &sumAndDifference, NULL, "S:ii", "Add and subtract two integers."); /* Call the appropriate method. */ xmlrpc_cgi_process_call(); /* Clean up our CGI library. */ xmlrpc_cgi_cleanup(); } RpC·é½ßÌüÍð¦µÜ· - bash$ CGI_CFLAGS=`xmlrpc-c-config cgi-server --cflags` bash$ CGI_LIBS=`xmlrpc-c-config cgi-server --libs` bash$ gcc $CGI_CFLAGS -o sumAndDifference.cgi sumAndDifference.c $CGI_LIBS ±êªI¹µ½çAsumAndDifference.cgi ðEFuT[oÌ cgi-bin fB NgÉRs[µÄ¾³¢B ªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªª 9. Java ÅÌ XML-RPC Ìg¢û Hannes Wallnfer Í Java p XML-RPC ÌDê½À <http://helma.at/hannes /xmlrpc/>ðñµÄ¢Ü·B CXg[ÍAzz¨ð_E[hµÄAunzip µÄA CLASSPATH É *.jar t@CðÇÁµÜ·BUnix VXeãÅAÌüÍÉæè±Ììƪ s¦Ü·B bash$ unzip xmlrpc-java.zip bash$ cd xmlrpc-java/lib bash$ CLASSPATH=`pwd`/openxml-1.2.jar:`pwd`/xmlrpc.jar:$CLASSPATH ªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªª 9.1. Java NCAg ÌvOR[hð JavaClient.java ƵÄt@CÉÛ¶µÄ¾³¢ B import java.util.Vector; import java.util.Hashtable; import helma.xmlrpc.*; public class JavaClient { // The location of our server. private final static String server_url = "http://xmlrpc-c.sourceforge.net/api/sample.php"; public static void main (String [] args) { try { // Create an object to represent our server. XmlRpcClient server = new XmlRpcClient(server_url); // Build our parameter list. Vector params = new Vector(); params.addElement(new Integer(5)); params.addElement(new Integer(3)); // Call the server, and get our result. Hashtable result = (Hashtable) server.execute("sample.sumAndDifference", params); int sum = ((Integer) result.get("sum")).intValue(); int difference = ((Integer) result.get("difference")).intValue(); // Print out our result. System.out.println("Sum: " + Integer.toString(sum) + ", Difference: " + Integer.toString(difference)); } catch (XmlRpcException exception) { System.err.println("JavaClient: XML-RPC Fault #" + Integer.toString(exception.code) + ": " + exception.toString()); } catch (Exception exception) { System.err.println("JavaClient: " + exception.toString()); } } } ªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªª 9.2. Ƨ^ Java T[o ÌvOR[hð JavaServer.java ƵÄt@CÉÛ¶µÄ¾³¢ B import java.util.Hashtable; import helma.xmlrpc.*; public class JavaServer { public JavaServer () { // Our handler is a regular Java object. It can have a // constructor and member variables in the ordinary fashion. // Public methods will be exposed to XML-RPC clients. } public Hashtable sumAndDifference (int x, int y) { Hashtable result = new Hashtable(); result.put("sum", new Integer(x + y)); result.put("difference", new Integer(x - y)); return result; } public static void main (String [] args) { try { // Invoke me as . WebServer server = new WebServer(8080); server.addHandler("sample", new JavaServer()); } catch (Exception exception) { System.err.println("JavaServer: " + exception.toString()); } } } ªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªª 10. PHP ÅÌ XML-RPC Ìg¢û Edd Dumbill Í PHP p XML-RPC ðÀµÄ¢Ü·BUsefulInc XML-RPC EF uTCg <http://xmlrpc.usefulinc.com/>©ç_E[hÅ«Ü·B zz¨ðCXg[·éÉÍA»êððµÄA xmlrpc.inc Æ xmlrpcs.inc ð È½Ì PHP XNvgªüÁÄ¢éÌƯ¶fBNgÉ Rs[µÜ·B ªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªª 10.1. PHP NCAg ÌXNvgÍEFuy[WÌÉ XML-RPC R[ðgÝÞû@ð¦µÜ ·B XML-RPC PHP Demo send($message); // Process the response. if (!$result) { print " Could not connect to HTTP server. "; } elseif ($result->faultCode()) { print " XML-RPC Fault #" . $result->faultCode() . ": " . $result->faultString(); } else { $struct = $result->value(); $sumval = $struct->structmem('sum'); $sum = $sumval->scalarval(); $differenceval = $struct->structmem('difference'); $difference = $differenceval->scalarval(); print " Sum: " . htmlentities($sum) . ", Difference: " . htmlentities($difference) . " "; } ?> ȽÌEFuT[oª PHP XNvgðÀsµÈ¢êAÇÁîñð¾é½ ßÉ PHP ÌEFuTCg <http://www.php.net/>ð©Ä¾³¢B ªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªª 10.2. PHP T[o ÌXNvgÍ PHP ðpµ½ XML-RPC T[oÌÀÌû@ð¦µÜ·B getParam(0); $x = $xval->scalarval(); $yval = $params->getParam(1); $y = $yval->scalarval(); // Build our response. $struct = array('sum' => new xmlrpcval($x + $y, 'int'), 'difference' => new xmlrpcval($x - $y, 'int')); return new xmlrpcresp(new xmlrpcval($struct, 'struct')); } // Declare our signature and provide some documentation. // (The PHP server supports remote introspection. Nifty!) $sumAndDifference_sig = array(array('struct', 'int', 'int')); $sumAndDifference_doc = 'Add and subtract two numbers'; new xmlrpc_server(array('sample.sumAndDifference' => array('function' => 'sumAndDifference', 'signature' => $sumAndDifference_sig, 'docstring' => $sumAndDifference_doc))); ?> ȽÍÊíA http://localhost/path/sumAndDifference.php Ìæ¤ÈàÌ ðÄÑo·Åµå¤B ªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªª 11. Microsoft .NET ÅÌ XML-RPC Ìg¢û Charles Cook Í±Ì HOWTO pÌDê½Vµ¢Íð·MÅ·BeÍI C <http://www.cookcomputing.com/misc/howto.txt>Å©çêÜ·B»Ìy [WªpðÁµ½çALinux Documentation Project Å XML-RPC HOWTO ÌVÅ <http://www.linuxdoc.org/HOWTO/XML-RPC-HOWTO/index.html> ðTµÄ¾³ ¢B ªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªª 12. Ruby ÅÌ XML-RPC Ìg¢û (XML-RPC HOWTO ̱ÌÍÍ Michael Neumann ªCOæñµÄêܵ½ B) Ruby <http://www.ruby-lang.org/> ÍIuWFNgwüXNvg¾êÅ·B ùÉú{Åͽ̤DÒª¨èA¼ÅàlCªo èÜ·B Ruby Å XML-RPC ðg¤ÉÍAßÉgc³lÌ xmlparser W [ (James Clark Ì expat parser pbp[) ðCXg[µÈ¯êÎÈèÜ ¹ñB±êÍ Ruby Application Archive <http://www.ruby-lang.org/en/ raa.html> ũ¯çêÜ·B »µÄÌR}hðgÁÄ xmlrpc4r <http://www.s-direktnet.de/ homepages/neumann/xmlrpc4r/index.html> ðCXg[µÈ¯êÎÈèܹ ñB bash$ tar -xvzf xmlrpc4r-1_2.tar.gz bash$ cd xmlrpc4r-1_2 bash$ su root -c "ruby install.rb" ªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªª 12.1. Ruby NCAg PÈ Ruby NCAgð¦µÜ· - require "xmlrpc/client" # Make an object to represent the XML-RPC server. server = XMLRPC::Client.new( "xmlrpc-c.sourceforge.net", "/api/sample.php") # Call the remote server and get our result result = server.call("sample.sumAndDifference", 5, 3) sum = result["sum"] difference = result["difference"] puts "Sum: #{sum}, Difference: #{difference}" ªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªª 12.2. Ruby T[o PÈ Ruby T[oð¦µÜ· - require "xmlrpc/server" s = XMLRPC::CGIServer.new s.add_hanlder("sample.sumAndDifference") do |a,b| { "sum" => a + b, "difference" => a - b } end s.serve ܽAÌæ¤É±ÆàÅ«Ü·B require "xmlrpc/server" s = XMLRPC::CGIServer.new class MyHandler def sumAndDifference(a, b) { "sum" => a + b, "difference" => a - b } end end s.add_handler("sample", MyHandler.new) s.serve Ç¿çÌT[oàƧ^ÅÀs·éÉÍAvOÌñsÚð s = XMLRPC::Server.new(8080) É«©¦Ä¾³¢B ªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªª 13. Æ©IȾêÅÌ XML-RPC Ìg¢û XML-RPC ÌÀÍȺɦ·Æ©IÈvO~O¾ê¨æÑ«ÅpÅ «Ü·B ªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªª 13.1. K ÅÌ XML-RPC Ìg¢û (XML-RPC HOWTO ̱ÌÍÍ Christian Langreiter ªCOæñµÄêÜ µ½B) K <http://www.kx.com/> Íïv¨æÑf[^x[XJÅgíêé¾êÅ ·BK p XML-RPC ðCXg[·éÉÍ Kx ÌEFuTCg <http:// www.langreiter.com/k/kxr>©ç_E[hµÜ·BðµÄ È½Ì .k v Oð۵ĢéfBNgÉt@CðRs[µÜ·B Z¢NCAgð¦µÜ· - \l kxr server:("localhost";"/cgi-bin/sumAndDifference.cgi"); .kxr.c[server;"sumAndDifference";2 3] »µÄT[oð¦µÜ· - \l kxrsc .kxr.sm: ,("sumAndDifference";{.((`sum;+/x);(`difference;-/x))}) ³çɽÌáªzz¨ÌÉ èÜ·B ªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªª 14. XML-RPC T|[gªgÝÜê½AvP[V ¢Â©ÌêÊIÈ Linux AvP[VÍ XML-RPC ÌT|[gðµÄ¢ Ü·B±êçÍùɼÌƱëÅྪ³êÄ¢éÌÅA±±ÅÍåÉ»ÌL ÖÌ|C^ð¦µÜ·B ªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªª 14.1. Zope Zope ÅÌ XML-RPC ÌgpÉÖ·éLÍɦ·EFu©çüèÅ«Ü·B E Jon Udell Éæé Zope ÅÌ XML-RPC vO~O <http:// www.byte.com/column/BYT19991021S0014> E UserLand.Com Ì Zope XML-RPC <http://linux.userland.com/stories/ storyReader$18> ªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªª 14.2. KDE 2.0 KDE 2.0 Í Kurt Ganroth Ì kxmlrpc f[ <http:// kdecvs.stud.fh-heilbronn.de/cvsweb/kdebase/kxmlrpc/>ðÜÝAf[Í XML-RPC ðgÁ½ KDE AvP[V̽ß̨V§ÄðµÜ·B Python Å©ê½Z¢AvP[VÌá <http:// kdecvs.stud.fh-heilbronn.de/cvsweb/kdebase/kxmlrpc/test/testxmlrpc.py? rev=1.6&content-type=text/x-cvsweb-markup>ª èÜ·B»êÍ kxmlrpc Ö Ú±·éA KDE ÌZ^ðì·éAKDE g[_ðõ·éÆ¢Á½û@𠦵ܷB Ƚª»Ì¼ÉLâvOÌáðÁÄ¢éêA Section 15.3> ð ©Ä¾³¢BBÍ KDE ðLq·éãÅàÁƽÌîñ𿽢ÆvÁ ĢܷB ªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªª 15. ±Ì¶É墀 ±Ì¶Í Linux Documentation Project <http://www.linuxdoc.org/> É ³êĢܷBDave Winer ¨æÑlXÈ XML-RPC CuÌ·×ÄÌÇ ÒɴӵܷB ªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªª 15.1. ±Ì¶ÌVÅ ±Ì¶ÌVÅÍ Linux Documentation Project <http://www.linuxdoc.org/ HOWTO/XML-RPC-HOWTO/index.html> ÌEFuTCgÅüèÅ«Ü·B ܽÌtH[}bgÅàñ³êĢܷB PDF <http://www.ibiblio.org/ pub/Linux/docs/HOWTO/other-formats/pdf/XML-RPC-HOWTO.pdf>, gzipped HTML <http://www.ibiblio.org/pub/Linux/docs/HOWTO/other-formats/html/ XML-RPC-HOWTO-html.tar.gz> ¨æÑ ASCII text <http://www.ibiblio.org/ pub/Linux/docs/HOWTO/XML-RPC-HOWTO>B ªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªª 15.2. XML-RPC HOWTO ÌñeÒ Ruby ÉÖ·éÍÍ Michael Neumann (neumann AT s-direktnet DOT de) Éæ èñe³êܵ½BK ÉÖ·éÍÍ Christian Langreiter (c DOT langreiter AT synerge DOT at) Éæèñe³êܵ½B [óFãL̼OÌãÌ () àÍ[AhXð¦µÄ¢Ü·BuATvÍu @vAuDOTvÍu.vÉu«©¦ÄAóð·êÎ[AhXª¾çê Ü·B] ñeÒÍ»ÌÍÌnßÉLü³êĢܷB ªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªª 15.3. ¼ÌîñÌño Ê̾êâ«ÅÌNCAgâT[oÌáðÁÄ¢éêA±Ì¶É ÇÁµ½¢ÆÆÄàvÁÄÜ·BVµ¢GgðÇÁ·é½ßÉAɦ· îñªKvÅ·B E XML-RPC ðgpµ½ÀÌ URL E CXg[è E ®SÈÀsÅ«évO E KvÈçRpCè ¶ÉLÚµÄà©ÜíÈ¢ E-mail AhX - á¦Î xmlrpc-c-devel [ OXg <http://xmlrpc-c.sourceforge.net/lists.php> àµÍA¼Ú Ì Eric Kidd <mailto:eric.kidd@pobox.com>B îñð¨Ò¿µÄ¢Ü·I ªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªª 16. ú{êóÉ墀 ú{êóÍ Linux Japanese FAQ Project ªs¢Üµ½B|óÉÖ·é²Ó© Í JF vWFNg <JF@linux.or.jp> ¶ÉAµÄ¾³¢B 0.8.0j |ó: ì{_ê <hng@ps.ksky.ne.jp> Z³: çUTi³ñ <ysenda@pop01.odn.ne.jp> RcTç³ñ <trueheart@anet.ne.jp>