JSON-RPC、XML-RPC、SOAP三者的关系

JSON-RPC规范:http://json-rpc.org/wiki/specification

XML-RPC规范:http://www.xmlrpc.com/spec

SOAP规范:http://www.w3.org/TR/2000/NOTE-SOAP-20000508/#_Toc478383487

参考:http://weblog.masukomi.org/writings/xml-rpc_vs_soap.htm

三者都是为了实现RPC中的消息交换,并且都没有定义传输协议。不过为了更方便在网络中传输,而且由于HTTP的无状态性,都使得HTTP为这三者的常用的传输协议。下面例子也是基于HTTP协议的

XML-RPC和SOAP都是基于XML格式的消息交换:

XML-RPC非常简单,定义了几种基本类型、匿名结构体、匿名数组;

SOAP除了基本类型、命名结构体、命名数组以外,还可以自定义类型,能使用多态的方法调用方式

而JSON-RPC是基于JSON格式的消息交换,JSON比XML更加轻巧,并且非常容易在页面JS中使用,其他特点与XML-RPC类似

下面是使用这几种协议发送请求的例子:

XML-RPC

Xhtml代码
  1. POST /RPC2 HTTP/1.0  
  2. User-Agent: Frontier/5.1.2 (WinNT)  
  3. Host: betty.userland.com  
  4. Content-Type: text/xml  
  5. Content-length: 181  
  6.   
  7.   
  8.   
  9. <?xml version="1.0"?>  
  10. <methodCall>  
  11.    <methodName>examples.getStateName</methodName>  
  12.    <params>  
  13.       <param>  
  14.          <value><i4>41</i4></value>  
  15.          </param>  
  16.       </params>  
  17.    </methodCall>  

SOAP:

Xhtml代码
  1. POST /StockQuote HTTP/1.1  
  2. Host: www.stockquoteserver.com  
  3. Content-Type: text/xml; charset="utf-8"  
  4. Content-Length: nnnn  
  5. SOAPAction: "Some-URI"  
  6.   
  7. <SOAP-ENV:Envelope  
  8.   xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"  
  9.   SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>  
  10.    <SOAP-ENV:Header>  
  11.        <t:Transaction  
  12.            xmlns:t="some-URI"  
  13.            SOAP-ENV:mustUnderstand="1">  
  14.                5  
  15.        </t:Transaction>  
  16.    </SOAP-ENV:Header>  
  17.    <SOAP-ENV:Body>  
  18.        <m:GetLastTradePrice xmlns:m="Some-URI">  
  19.            <symbol>DEF</symbol>  
  20.        </m:GetLastTradePrice>  
  21.    </SOAP-ENV:Body>  
  22. </SOAP-ENV:Envelope>  

JSON:

Javascript代码
  1. --> { "method": "echo", "params": ["Hello JSON-RPC"], "id": 1}  
  2. <-- { "result": "Hello JSON-RPC", "error": null, "id": 1} 

PHP SOAP实例讲解

一、什么是soap,什么是wsdl,为什么要用他们

SOAP是基于XML和HTTP通信协议,xml各种平台,各种语言都支持的一个种语言。http呢它得到了所有的因特网浏览器及服务器的支持。

WSDL 指网络服务描述语言 (Web Services Description Language),是一种使用 XML 编写的文档。这种文档可描述某个 Web service。它可规定服务的位置,以及此服务提供的操作。

我是做php的,你是java的,他是做.net,如果我们三个之间要进行通信,要进行数据交换,怎么办呢?我们需要一个能和我们都能通信的工具。soap,wsdl被创造出来,使得运行在不同的操作系统并使用不同的技术和编程语言的应用程序可以互相进行通信。

二、实例

如果php要使用soap的话,通常做法是,添加了一下php的soap模块,在php.ini里面加上soap.so,下面介绍一个不要添加soap.so文件,也可以实现soa

  1. <?php    
  2. //包函nusoap.php  
  3. require_once('./lib/nusoap.php');  
  4.   
  5. //创建服务端  
  6. $server = new soap_server;  
  7.   
  8. //定义客户端调用方法  
  9. $server->register('hello');  
  10.   
  11. //调用方法以及参数  
  12. function hello($name) {  
  13.     return 'Hello, ' . $name;  
  14. }  
  15.   
  16. $HTTP_RAW_POST_DATA = isset($HTTP_RAW_POST_DATA) ? $HTTP_RAW_POST_DATA : '';  
  17. $server->service($HTTP_RAW_POST_DATA);  
  18. ?>    

p的方法

nusoap是php写的一个功能文件,包涵进来就可以用了,网上很多自己去搜一下吧。

1、不使用wsdl

a、服务端helloworld2.php

b、客户端hello.php

  1. <?php    
  2. //包函nusoap.php  
  3. require_once('./lib/nusoap.php');  
  4. //新建一个soap客户端,调用服务端提供的wsdl  
  5. //$client = new soapclient('http://localhost/test/hellowsdl2.php?wsdl', true);  
  6. $client = new soapclient('http://localhost/test/helloworld2.php');  
  7. //查看一下是不是报错  
  8. $err = $client->getError();  
  9. if ($err) {  
  10.     //显示错误  
  11.     echo '<h2>Constructor error</h2><pre>' . $err . '</pre>';  
  12. }  
  13.   
  14. //调用服务端的方法  
  15. $result = $client->call('hello'array('person' => "this is a test"));  
  16.   
  17. echo '<h2>Result</h2><pre>';  
  18. print_r($result);  
  19. echo '</pre>';  
  20. ?>    

2、使用wsld

a、服务器端

  1. <?php    
  2. //包函nusoap.php  
  3. require_once('./lib/nusoap.php');  
  4. //新建一个soap服务  
  5. $server = new soap_server();  
  6. //初始化支持wsdl  
  7. $server->configureWSDL('hellowsdl2''urn:hellowsdl2');  
  8. //定义数据结构来接收数据  
  9. $server->wsdl->addComplexType(  
  10.     'Person',  
  11.     'complexType',  
  12.     'struct',  
  13.     'all',  
  14.     '',  
  15.     array(  
  16.         'firstname' => array('name' => 'firstname''type' => 'xsd:string'),//后面的type定义数据的类型,这个是string  
  17.         'age' => array('name' => 'age''type' => 'xsd:int'),//后面的type定义数据的类型,这个是int  
  18.         'gender' => array('name' => 'gender''type' => 'xsd:string')//后面的type定义数据的类型,这个是string  
  19.     )  
  20. );  
  21. $server->wsdl->addComplexType(  
  22.     'SweepstakesGreeting',  
  23.     'complexType',  
  24.     'struct',  
  25.     'all',  
  26.     '',  
  27.     array(  
  28.         'greeting' => array('name' => 'greeting''type' => 'xsd:string'),  
  29.         'winner' => array('name' => 'winner''type' => 'xsd:string')  
  30.     )  
  31. );  
  32. //服务器定义的soap调用方法  
  33. $server->register('hello',                    // 方法名字hello,方法就在下面  
  34.     array('person' => 'tns:Person'),          // 客户端传来的变量  
  35.     array('return' => 'tns:SweepstakesGreeting'),    //返回参数  
  36.     'urn:hellowsdl2',                         // soap名  
  37.     'urn:hellowsdl2#hello',                   // soap的方法名  
  38.     'rpc',                                    // 使用的方式  
  39.     'encoded',                                // 编码  
  40.     'test'                                    // 存档  
  41. );  
  42. //定义上面注册过的函数hello  
  43. function hello($person) {  
  44.     $greeting = 'Hello, '.$person['firstname'].'. It is nice to meet a '.$person['age'].' year old '.$person['gender'].'.';  
  45.   
  46.     $winner =  'Scott';  
  47.     //要返回的数据  
  48.     return array(  
  49.         'greeting' => $greeting,  
  50.         'winner' => $winner  
  51.     );  
  52. }  
  53. // 请求时(试图)调用服务  
  54. $HTTP_RAW_POST_DATA = isset($HTTP_RAW_POST_DATA) ? $HTTP_RAW_POST_DATA : '';  
  55. $server->service($HTTP_RAW_POST_DATA);  
  56. ?>    

b、客户端

  1. <?php  
  2. //包函nusoap.php  
  3. require_once('./lib/nusoap.php');  
  4. //新建一个soap客户端,调用服务端提供的wsdl  
  5. //$client = new soapclient('http://localhost/test/hellowsdl2.php?wsdl', true);  
  6. $client = new soapclient('http://localhost/test/helloworld2.php');  
  7. //查看一下是不是报错  
  8. $err = $client->getError();  
  9. if ($err) {  
  10.  //显示错误  
  11.  echo '<h2>Constructor error</h2><pre>' . $err . '</pre>';  
  12. }  
  13. //要向服务端要传的参数  
  14. $person = array('firstname' => 'Willi', 'age' => 22, 'gender' => 'male');  
  15.   
  16. //调用服务端的方法  
  17. $result = $client->call('hello', array('person' => $person));  
  18. //错误审核  
  19. if ($client->fault) {  
  20.  echo '<h2>Fault</h2><pre>';  
  21.  print_r($result);  
  22.  echo '</pre>';  
  23. else {  
  24.  $err = $client->getError();  
  25.  if ($err) {  
  26.  echo '<h2>Error</h2><pre>' . $err . '</pre>';  
  27.  } else {  
  28.  echo '<h2>Result</h2><pre>';  
  29.  print_r($result);  
  30.  echo '</pre>';  
  31.  }  
  32. }  
  33. //显示请求信息  
  34. echo '<h2>Request</h2>';  
  35. echo '<pre>' . htmlspecialchars($client->request, ENT_QUOTES) . '</pre>';  
  36. //显示返回信息  
  37. echo '<h2>Response</h2>';  
  38. echo '<pre>' . htmlspecialchars($client->response, ENT_QUOTES) . '</pre>';  
  39. //显示调试信息  
  40. echo '<h2>Debug</h2>';  
  41. echo '<pre>' . htmlspecialchars($client->debug_str, ENT_QUOTES) . '</pre>';  
  42. ?>  

上面二个例子不管是客户端,还是服务器端,都是用php写的,你可以试着用多种语言来写,来测试一下。不管你是用php的模块,还是用nusoap,里面具体方法就不在这多说了,手册里面都有。

 

 

 

 SOAP在这里就不用介绍了,  这里只是简单的实现一个SOAP的实例, 不多说 ,看代码吧。 soap分为server和client, 我们要使client去调用server的代码. 首先看server短的代码:

 

这个是server端的代码: server.php

<?php

    //声明一个函数add() ,并返回它的值
        function add($a,$b){
        return $a+$b;
        }

    //实例化一个SoapServer对象, 并将add函数注册成为其方法
        $server = new SoapServer(null,array('uri'=>'http://localhost/')); //指定server端代码的URI(资源标志符)
        $server->addFunction("add");
        $server->handle();
?>

然后使用client端的代码来调用server端的代码: client的代码也很简单: 如下:

这个是client端的代码 client.php

<?php

    //建立一个参数数组,存储要访问的提供soap服务的计算机的地址与程序
        $arrOptions=array(
            'uri'=>'http://localhost/',
            'location'=>'http://localhost/soap/server.php',  //注意: 这个location指定的是server端代码在服务器中的具体位置, 我的是在本地根目录下的soap目录中,
            'trace'=>true,
        );
        $soapObject = new SoapClient(null,$arrOptions); //实例化客户端对象
        echo $soapObject->add(20,30); //调用服务器端的函数add并返回值50
?>

ok, 结束了 !