WebService详解

1998年,一个名叫Dave Winer的程序员设计出了 XMLRPC,即XML Remote Procedure Call(XML 远程程序调用)。
xml-rpc是使用http协议做为传输协议rpc机制,使用xml(可扩展标记语言)格式文本的方式传输命令和数据。一个rpc系统,必然包含2个部分:
  • rpc client(rpc客户端),用来向rpc server调用方法,并接收方法的返回数据。
  • rpc server(rpc服务器端),用于响应rpc client的请求,执行方法,返回结果。
RPC(Remote Procedure Call的缩写,即 远程方法调用,或远程过程调用) 是一种在本地机器上调用远程机器上的程序(方法)的技术,这个过程也被大家称为“分布式计算”,是为了提高各个独立机器的“ 互操作性 ”而发明出来的技术。

后来,xml-rpc演变成了SOAP(Simple Object Access Protocol,简单对象访问协议)。

1. WebService 简介
Web   Service(即网页服务)是一个 平台独立的、低耦合的、自包含的、基于可 编程的web应用程序,它使用开放的 XML 标准描述、发布、发现、协调和配置这些应用程序,用于开发分布式的互操作的 应用程序
现在,有很多的开放API都是基于XML,我们只需读取服务器端生成的一个XML文件,用可以用任何语言解析该XML字符串。这种方式利用了XML跨平台的通用性,使用简单的文本和HTTP请求实现了WebService。

传统的WebService,通过WSDL( Web Services Description Language,网页服务描述语言)生成一个WSDL文件,WSDL是基于XML的语言,用于描述WebService及其函数、参数和返回值。WSDL文档是一个可供机器和人阅读的描述了如何使用WebService的API文档。而SOAP提供了标准的RPC方法来调用WebService。这种传统的WebService比较笨重,也越来越不受欢迎。因此,这里介绍一个轻量级的、高效的WebService解决方案——PHPRPC。

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

PHPRPC支持十多种常见的编程语言,包括PHP、ASP、Java、C++、Delphi、Javascript、Python、Ruby、Perl等。了解详情可访问PHPRPC官方网站  http://www.phprpc.org/zh_CN/

假设有一个需求:由于某种原因,PHP需要调用Java的方法(因为PHP无法对硬件和系统资源进行操作,如:纯PHP管理考勤机、打印机等,很难只用PHP实现),就需要用Java发布一个方法,供PHP调用。

提示:PHPRPC的功能不止这些,现在还演变出了商业版的Hprose,其功能更加强大。

如何在PHP中调用Java类的方法?可通过php java bridge或ICE等中间件来实现,还有另外一种方法就是WebService,这里通过PHPRPC实现。
准备工作:到PHPRPC的官网下载对应的软件包,解压后,拷贝至项目目录。

首先,在服务器端用Java写一个类(如MyHello类),作为服务的发布,类中有一个方法(如say方法,打印信息),提供的打印服务如下:
package cn.sin.book.dao;
public class MyHello {
public String say(String name) {
return "Hello "+name;
}
}
然后,用Java新建一个文件rpc.jsp,发布这个服务(代码略过)。之后,我们就可以在PHP中调用它(当然也可以在Java中调用它)。
这里只介绍用PHP作为客户端调用Java服务,代码如下:

   
   say('jack');
?>
可以看出,这种方式无论是服务器端的发布还是客户端的调用都非常简单,没有繁琐的服务器配置,也没有一堆难以理解的XML文件,速度上也有很大优势。

那么,如果用PHP客户端调用PHP服务器端呢?这就更简单了,具体有以下四个步骤:

(1)下载 PHPRPC 3.0.1 for PHP的安装包,解压后,将文件夹的名称简化为 phprpc
其中,bigint.php、compat.php、phprpc_date.php、xxtea.php属于公共文件。不论是客户端还是服务器端都需要这些文件。
phprpc_client.php是客户端文件。
dhparams文件夹、 dhparams.php、phprpc_server.php是服务器端需要的文件。

(2)部署服务器端和客户端,即将所需文件拷贝至项目目录(为了方便演示,这里把服务器端和客户端部署在同一台服务器上)。

(3)写服务器端代码并发布,如新建一个rpc_server.php,代码如下:

   
   add('helloWorld', 'Hello');
$server->start();
?>
(4)写客户端代码,新建一个rpc_client.php,代码如下:

    
    helloWorld('jack');
?>
最后,在浏览器中访问 http://demo.com/rpc_client.php,查看测试的结果。
如果你的php版本大于5.4,可能会报错” Cannot  redeclare gzdecode ...“,这是因为 PHP 5.4 以上版本已经自包含了gzdecode()函数,而开发者又在phprpc软件包里的 compat.php文件中定义了gzdecode()函数,导致该函数被重复定义。解决方法如下:
找到compat.php文件中的 gzdecode()函数的定义代码,将其用下面的代码包裹起来即可。
if(!function_exists('gzdecode')){ 
    // 将 gzdecode()函数的定义代码放在此处
}

3. WebService的实现模式
PHP支持两种Web服务的模式:WSDL和non WSDL,为了便于理解,先介绍Web服务的两种实现模式。Web服务主要有两种实现模式: 契约先行(Contract First)模式和代码先行(Code First)模式。

契约先行模式的实现中,首要工作是定义针对这个Web服务接口的WSDL( Web Services Description Language,网页服务描述语言)文件。WSDL文件中描述了Web服务的位置、可提供的操作集及其他属性。
WSDL文件也就是Web服务的“契约”。契约订立之后,再据此进行服务器端和客户端的应用程序开发。这种模式对应WSDL模式。

WSDL文件包括五个部分:Types、Message、PortType、Binding和Service。
Types:类型定义独立于语言,对应于SOAP消息中要传输的元素信息的定义。
Message:每个Web方法对应两个Message定义in和out,而Message的定义包含头和体。
PortType:每个WebService对应一个PortType,其中又包含了对其发布的方法、操作。
Bindings:指定PortType中每个操作(类和方法)的绑定信息,包含input和output消息的格式。
Service:每个WebService绑定的port信息。

关于WSDL文件的详细介绍可查看: http://www.w3school.com.cn/wsdl/

与契约先行模式不同,代码先行模式中,第一步工作是实现Web服务器端,根据服务器端的实现,用某种方法(自动生成或手工编写)生成WSDL文件。但是,由于PHP本身并没有提供从Web服务实现代码中生成WSDL文件的方法,因此就要以non WSDL模式连接服务器端,即不通过WSDL文件创建SoapServer和SoapClient示例,而是直接向构造函数传递必要的参数。当然,代码先行模式也有其他的解决方法,一些集成的PHP开发工具(如Zend Studio)提供了根据Web服务实现代码生成WSDL文件的功能。

有的情况下,对方约定必须使用SOAP通信,所以下面来了解SOAP是什么。

4. 简单对象访问协议SOAP
在 PHP 5 之前,使用第三方产品NuSOAP辅助开发WebService,不过这个产品已经停止开发了。PHP 5 新增了内置的SOAP扩展(ext/soap),从此开发基于SOAP的应用程序不需要下载额外的扩展库和代码包了。

SOAP(Simple Object Access Protool,简单对象访问协议)是基于XML的、可扩展的通信协议。SOAP提供了一种标准,使运行在不同平台、不同编程语言编写的应用程序可以互相通信。SOAP具有可扩展性和跨平台的特点,被广泛用作WebService的通信协议。SOAP中主要有以下几个类:

(1)服务类SoapServer
SoapServer类用来开发Web服务器端的应用程序。这个类中包含创建、设置和操作Web服务的方法。向Web服务中添加操作(Operation)有两种方式:
  • 直接添加已定义的函数
  • 添加已定义好的类,从而将该类的公有成员方法添加到Web服务中

(2)客户端类SoapClient
SoapClient类用于开发Web服务的客户端程序。内置的可用的成员函数主要有创建客户端实例、调用可用操作、查询可用操作和数据类型等。除此之外,还包括了可用于程序调试的函数、获取上次请求和应答的SOAP数据。

(3)参数类SoapHeader、SoapParam、SoapVar
SoapHeader类用来构造SOAP头,SOAP头可以对SOAP的能力进行必要的扩展,主要用于简单的身份认证。
SoapParam和SoapVar封装了放入SOAP请求中的数据,主要在non WSDL模式下使用。
提示:在WSDL模式下,SOAP请求的参数通过数组方式包装,SOAP扩展根据WSDL文件将这个数组转化为SOAP请求中的数据部分,所以并不需要SoapParam和SoapVar这两个类。而non WSDL模式没有提供WSDL文件,所以必须通过这两个类进行包装。

(4)异常类SoapFault
SoapFault类继承自PHP的Exception类,用来实现SOAP的异常处理机制,由SOAP服务器端抛出。SOAP客户端接收该类的实例,用于获取有用的调试信息。

下面进行一个简单的SOAP演示。
首先,是服务器端的功能实现,新建一个soap_server.php文件,代码如下:

    
    
其次,发布服务器端所提供的函数或类,新建一个soap_proxy.php文件,代码如下:

    
    "http://test-uri"));
// $soap->addFunction('getTime');
$soap->setClass('Member');  // 这里只发布已定义好的类
$soap->handle();
?>
然后,实现客户端,新建一个soap_client.php文件,代码如下:

    
        'http://demo.com/soap_proxy.php',
        'uri'        =>    'http://test-uri',
        'style'        =>    SOAP_RPC,
        'use'        =>    SOAP_ENCODED,
        'trace'        =>    1,
        'exceptions'=>    0
);
$client = new SoapClient(null, $options);
// $rt = $client->getTime();
$addresult = $client->add(2,3);
// echo "函数调用结果是:".$rt."\r\n";
echo "类方法调用结果是:".$addresult."\r\n";
?>
最后,在浏览器中访问  http://demo.com/soap_client.php,查看测试的结果。
如果运行时报错,请检查 soap_proxy.php文件和soap_client.php文件是否有疏忽的地方。

注意:soap_proxy.php中注释的一行和soap_client.php中注释的两行,是为了不在服务器端同时混合发布类和函数,也不在一个客户端同时调用发布的类和函数,也不要在一个服务接口发布多个类,否则,会出现异常。

尽管SOAP的名字叫做简单对象访问协议,实际上并不简单。这里不对SOAP作深究,也不推荐使用SOAP。其实,JSON、HTTP、Socket等在某种意义上也属于WebService的范畴。

上面讲的WebService都是RPC样式的Web服务,还有一种Web服务是通过RESTful来实现的。在 REST 样式的Web服务中,每个资源都有一个地址,由于其轻量级和通过HTTP直接传输数据的特性,RESTful Web服务已经成为最常见的Web服务解决方案。由于篇幅原因,这里不作讲解。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值