Web Service如何实现跨平台网络通讯?
Posted 乌戈勒
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Web Service如何实现跨平台网络通讯?相关的知识,希望对你有一定的参考价值。
Web Service如何实现跨平台网络通讯?
一、目录
- Web Service的介绍
- SOAP协议
- WSDL介绍
- Web Service的ios实战
二、Web Service的介绍
WebService是一种跨编程语言和跨操作系统平台的远程调用技术。
WebService其实就是建立可互操作的分布式应用程序的新平台,是一个平台,是一套标准。
它定义了应用程序如何在Web上实现互操作性,你可以用任何你喜欢的语言,在任何你喜欢的平台上写Web service ,只要我们可以通过Web service标准对这些服务进行查询和访问。
1、如何理解它的跨语言、跨平台的?
1)跨编程语言:
就是说服务端程序可以是C#、JAVA、php、C++,客户端可以是Objective-C、安卓、WinPhone下的c#编写;
2)跨操作系统平台:
则是指服务端程序和客户端程序可以在不同的操作系统上运行。
A. 首先要了解一下传统业务接口请求和web service网络通信有什么区别?
(传统接口请求是怎样的?RPC请求风格、TAF框架)
1)传统http请求:
服务器会根据客户端传递过来的具有标准语义的通用接口也就是URL去定位到资源,这些URL能够被一些中间组件或者提供服务来源的服务器进行解析,比如要获取一个列表数据,它就会去查询相关数据库,拿到数据返回给客户端;
2)RPC请求风格/机制:
根据语言的API进行定义,可以直接做到不同计算机下不同语言的函数API调用;
多线程非阻塞、网络线程和业务线程隔离;
(web service就类似RPC方式,实现了不同平台下不同语言的API函数调用)
类似API函数调用:
Web service其实就类似一个应用程序向外界提供了一套API,通过web进行调用,这一点跟传统业务http接口请求有差异;
B. 如何实现类似同一台计算机下同一语言的函数调用的?
(传统的函数调用是怎样的?客户端和服务器的远程调用,做到类似本地调用)
需要依赖一种规范和标准,才能做到,它是通过XML文档的形式,遵循soap协议规范,各端按照这套公认的规范进行序列化、反序列化(简称封包、解包)、网络请求处理操作,就可以实现所谓的API函数调用
C. 理解一下JCE-WUP协议、TAF框架
重点概念:
序列化、反序列化、封包、解包
RPC请求风格、异构环境的分布式调用、互操作
总结
其实可以从多个角度来理解WebService。
1)从表面上看,WebService就是一个应用程序向外界暴露出一个能通过Web进行调用的API,也就是说能用编程的方法通过Web来调用这个应用程序。
我们把调用这个WebService的应用程序叫做客户端,而把提供这个WebService的应用程序叫做服务端。
2)从深层次看,WebService是建立可互操作的分布式应用程序的新平台,是一个平台,是一套标准。
它定义了应用程序如何在Web上实现互操作性,你可以用任何你喜欢的语言,在任何你喜欢的平台上写Web service ,只要我们可以通过Web service标准对这些服务进行查询和访问。
2、Web service有什么用?
在传统的网络请求中,存在各种各样的函数调用。
比如,我们知道一个天气预报的程序模块M,它提供一个查询天气的方法A,客户端想要查广东的天气。
会先找到这个模块M,然后向方法A传递参数P(广东),服务器收到请求并处理完成后,会向客户端返回处理结果R。
这个就是我们最常见的一个函数调用的例子。
这种函数和方法的调用,通常是发生在同一台机器的同一个程序语言环境下的。
我们需要一种能在不同计算机的不同编程语言的应用程序之间,可以通过网络通信,实现函数的相互调用的技术。
Web Service就是应这种需求而诞生的。
3、Web Service的大致结构
Web Service = SOAP + HTTP + WSDL
用一段话描述就是:
SOAP协议是Web Service的主体,它是通过HTTP或SMTP等协议进行通讯的,而它自身是使用XML文档来描述程序的函数和方法,以及参数信息,从而完成不同主机的异构系统之间的计算机服务处理。
WSDL是Web Service的描述语言,也是一个XML文档,它是通过HTTP向公众发布,公众客户端程序关于某个具体的Web Service服务的URL信息,方法的命名,参数和返回值等信息。
三、SOAP协议是什么?
在回答这个问题之前,先来看另一个问题:
1、客户端与服务器的网络通信涉及几个问题。
提问1:
1)客户端需要知道提供相关服务的对象是哪个?接口是哪个?
2)传递的参数是什么?参数的类型是什么?接口返回值是什么?返回值的类型是什么?
3)如何处理不同语言下的数据类型转换问题?(传统接口请求一般是通过一份接口描述文档来解决的。)
回答:
这些就是SOAP协议要处理的问题。
(但凡要做到跨平台跨语言,都是要面临这样几个问题的。
TAF框架的JCE-WUP协议,就是要处理这些问题)
2、不同语言下的数据类型转换?
提问2:
既然可以做到跨平台跨语言,那函数调用的时候,
是如何实现不同语言下的数据类型转换的问题的?
回答:
如果要实现客户端和服务器的远程调用,类似本地调用那样,需要解决一个问题?
(客户端要调用Web远程服务器的方法,就要深入到Web远程服务器的内部,去了解它的编程语言,了解它的对象,以及对象相关的接口,还有一个数据类型转换相关的问题。
打个比方,一个字符串在OC中就是NSString类型,而在远程Web服务器,如果用Java写的话就是一个String类型,如果是C#写的话就是一个string类型。这里就要牵扯到客户端和服务器之间,远程对象调用的一些数据类型转换的问题。)
总结:
Simple Object Access Protocol简单对象访问协议。
它实际上是一种数据交换的规范和协议。
它的XML里面的元素或者说标签,都是规定好的,代表了某些特殊含义,后面会具体说到这个。
我们可以通过SOAP来描述一个字符串,一个int数据类型,或者一个对象,很好的解决了远程对象之间数据交换的问题。
SOAP是XML RPC的高级版。
它是一种基于XML的消息通讯格式,用于网络上,不同平台,不同语言的应用程序之间的通讯的一种网络通信协议。(Web Service之所以做到跨平台跨语言就是靠SOAP)
SOAP 协议提出来比较早,是从1998年由几个大公司共同提出来的。其中就有IBM、微软。目前SOAP 1.2版本是业界共同的标准。
SOAP = HTTP+XML,其实就是通过HTTP发XML数据。所以它也是一种基于http的应用层协议。
3、客户端与服务器之间的请求过程
提问3:
soap协议下的网络请求过程是怎样的?
回答:
我们发送一个请求的时候,客户端会先将这样一个SOAP协议的XML文档,拼接成一个请求的字符串,通过http的post请求,向服务器发出请求。服务器收到请求后,会以SOAP协议的XML文档的形式,返回给客户端,客户端再通过XML解析器,把返回的数据解析出来。
这里就牵扯到两部:
请求:牵扯到XML的拼装;
返回:牵扯到XML的解析;
&&题外话:
后面会详细讲解一下SOAP格式的数据包结构。
后面可以讲解一下iOS是如何解析XML数据的?
iOS系统也有对应的XML解析框架。
TBXML据说是性能最好,也是最常用的XML解析库。
4、SOAP协议的数据包结构是怎样的?
一条SOAP消息就是一个普通的XML文档。
包含以下元素:
(1)Envelope元素:标识XML 文档是一条 SOAP 消息
(2)Header元素:包含头部信息的XML标签
(3)Body元素:包含所有的调用和响应的主体信息的标签
(4)Fault元素:错误信息标签
(说明:SOAP的命名空间都在 http://www.w3.org/2001/12/soap-envelope 和 http://www.w3.org/2001/12/soap-encoding 中有声明)
5、SOAP消息结构
1、示例
<?xml version="1.0"?>
<soap:Envelope
xmlns:soap="http://www.w3.org/2001/12/soap-envelope"
soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding">
<soap:Header>
...
</soap:Header>
<soap:Body>
...
<soap:Fault>
...
</soap:Fault>
</soap:Body>
</soap:Envelope>
解析:
1)一条SOAP消息就是一个普通的XML文档。
Envelope元素与Body元素(包含调用和响应信息)必须存在;
Header元素(包含头部信息)和Fault元素(提供有关在处理此消息所发生的错误的信息)可以作为可选存在。
2)SOAP Envelope 元素
Envelope 元素是 SOAP 消息的根元素。它指明 XML 文档是一个SOAP 消息。
它的属性 xmlns:soap的值必须是http://www.w3.org/2001/12/soap-envelope。
3)SOAP encodingStyle 元素
encodingStyle 属性用于定义XML文档中使用的数据类型。
4)SOAP Header 元素
SOAP Header 元素主要包含actor 属性和mustUnderstand 属性
5)SOAP Body 元素
<?xml version="1.0"?>
<soap:Envelope
xmlns:soap="http://www.w3.org/2001/12/soap-envelope"
soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding">
<soap:Body>
<m:GetPrice xmlns:m="http://www.xxx.net/prices">
<m:Item>Apples</m:Item>
</m:GetPrice>
</soap:Body>
</soap:Envelope>
对象地址:http://www.xxx.net/prices
对象函数:GetPrice
函数参数:Apples
解析:
上面的例子就是请求苹果的价格的SOAP消息。
对应的请求响应SOAP消息如下:
<?xml version="1.0"?>
<soap:Envelope
xmlns:soap="http://www.w3.org/2001/12/soap-envelope"
soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding">
<soap:Body>
<m:GetPriceResponse xmlns:m="http://www.xxx.net/prices">
<m:Price>1.90</m:Price>
</m:GetPriceResponse>
</soap:Body>
</soap:Envelope>
对象地址:http://www.xxx.net/prices
对象函数:GetPriceResponse
函数返回值:1.90
6)SOAP Fault 元素
Fault 元素表示 SOAP的错误消息。它必须是 Body 元素的子元素。
且在一条 SOAP 消息中,Fault 元素只能出现一次。
2、HTTP协议中的SOAP 实例
下面是一个请求股票价格的Web Service示例。
1)SOAP 请求数据:
POST /InStock HTTP/1.1
Host: www.xxx.net
Content-Type: application/soap+xml; charset=utf-8
Content-Length: XXX
<?xml version="1.0"?>
<soap:Envelope
xmlns:soap="http://www.w3.org/2001/12/soap-envelope"
soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding">
<soap:Body xmlns:m="http://www.xxx.net/stock">
<m:GetStockPrice>
<m:StockName>IBM</m:StockName>
</m:GetStockPrice>
</soap:Body>
</soap:Envelope>
对象地址:http://www.xxx.net/stock
对象函数:GetStockPrice
函数参数:IBM
2)SOAP 响应数据:
HTTP/1.1 200 OK
Content-Type: application/soap+xml; charset=utf-8
Content-Length: XXX
<?xml version="1.0"?>
<soap:Envelope
xmlns:soap="http://www.w3.org/2001/12/soap-envelope"
soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding">
<soap:Body xmlns:m="http://www.xxx.net/stock">
<m:GetStockPriceResponse>
<m:Price>34.5</m:Price>
</m:GetStockPriceResponse>
</soap:Body>
</soap:Envelope>
对象地址:http://www.xxx.net/stock
对象函数:GetStockPriceResponse
函数返回值:34.5
&& 题外话
(它是基于HTTP的一种应用层协议,主要通过XML数据格式进行网络通信,SOAP = HTTP+XML)
(就好比如TAF框架的JCE-WUP协议,通过二进制数据进行网络通信)
1)SOAP协议下的客户端和服务器之间请求应答的一个过程是怎样的?
2)代码实例解析SOAP协议的数据包结构是怎样的?
3)为什么要用XML作为传输的数据格式,而不是JSON呢?
(这里就要提到我们网络通讯传输数据的两种格式XML和JSON)
四、WSDL的介绍
回答这个问题之前,先来看另一个问题。
提问1:
怎样向别人介绍你的 web service 有什么功能,提供这样功能的对象是什么?函数是哪个?代表什么含义?传递的参数是什么?参数类型,返回值是什么,类型又是什么等信息,以及不同语言下的数据类型转换等问题。
(这些都是WSDL需要解决的问题。)
回答:
传统的业务请求,服务器会向客户端提供一套服务的接口文档,甚至可能会口头上告诉需要使用它的web service的人。
这些方法至少都有一个严重的问题:
当程序员坐到电脑前,想要使用你的web service的时候,他们的开发工具如xcode无法给他们提供任何帮助,因为这些工具根本就不了解你的web service。
解决方法:
用机器能阅读的方式提供一个正式的描述文档。
web service描述语言(WSDL)就是这样一个基于XML的语言,用于描述web service及其函数、参数和返回值。
因为是基于XML的,所以WSDL既是机器可阅读的,又是人可阅读的,这将是一个很大的好处。
优势:
一些最新的开发工具既能根据你的web service生成WSDL文档,又能导入WSDL文档,生成调用相应web service的代码。
前面提到的SOAP协议提到了提供相关服务的对象是什么?接口是哪个?传参和返回值以及它们的类型是什么?
这些信息都是通过WSDL来向我们说明的。
简单来说,WSDL就是描述SOAP协议的一种语言。(这种语言是通过XML文档来体现的)
总结:
Web Services Description Language网络服务描述语言。
//*****************
1)举例说明一下。
比如前面提到的SOAP的一个请求苹果价格的例子。
SOAP的请求数据中,里面有一个元素GetPrice,这是什么意思?
为什么GetPrice里面又有Item元素呢?又代表什么含义?
这些都是在对应的XML schema中进行定义的,这样的一个XML schema文档就是一个WSDL描述文档。
WSDL文档中,定义了GetPrice这样一个函数元素,以及参数和参数类型等信息。
//*****************
2)WSDL在实际开发中是怎么用的?
我们在开发Web Service的时候,服务器端写完这些接口后,会先通过一些工具生成对应的WSDL文档,客户端可以通过WSDL了解到相关的服务信息。
客户端就可以根据WSDL文档,组装相应的SOAP请求信息,通过http请求发送服务请求。
3)WSDL文档的数据结构是怎样的?
了解SOAP协议,WSDL文档的结构,这些协议和规范理清楚之后,才能根据这些规范去实现一套工具,将wsdl文档生成对应平台的调用代码。
4)客户端是如何获取WSDL文档的呢?
WSDL文档是一种以.wsdl为后缀的文件。
服务器的接口编写完成,或者重新定义或者新增之后,就通过一些工具重新生成新的WSDL文档,通过这个WSDL文档来描述SOAP协议。
所以服务器Web Service与客户端之间,所传递的文档,是遵循SOAP协议,以及WSDL文档描述的一种XML格式。
Webservice服务发布之后,通过浏览器访问发布的+?wsdl即可获得wsdl文档。
1、Webservice服务发布之后,通过浏览器访问可以进行访问。
http://ws.webxml.com.cn/WebServices/MobileCodeWS.asmx
(WebXml.com.cn 国内手机号码归属地查询WEB服务,提供最新的国内手机号码段归属地数据)
2、+?wsdl即可获得对应web服务的wsdl文档。
http://ws.webxml.com.cn/WebServices/MobileCodeWS.asmx?wsdl
上面这个就是对应web服务的WSDL文档。
2、通过浏览器打开上面的WSDL文档后,右键另存为成XML文件。
MobileCodeWS.xml
5)举个栗子
C#写的一个Web Service的方法
public float GetPrice (string Apples)
<相关处理代码>
服务器端写完这个方法之后,可以通过一些工具,获得WSDL文档:
<s:element name=“GetPrice”>
<s:sequence>
<s:element name=“Item” type=“s:string”/>
</s:sequence>
</s:element>
<s:element name=“GetPriceResponse”>
<s:sequence>
<s:element name=“Price” type=“s:float”/>
</s:sequence>
</s:element>
五、iOS开发怎么用Web Service
1、Webservice服务发布之后,通过浏览器访问发布的+?wsdl即可获得wsdl文档。
http://ws.webxml.com.cn/WebServices/MobileCodeWS.asmx
(WebXml.com.cn 国内手机号码归属地查询WEB服务,提供最新的国内手机号码段归属地数据)
http://ws.webxml.com.cn/WebServices/MobileCodeWS.asmx?wsdl
上面这个就是对应web服务的WSDL文档。
2、通过浏览器打开上面的WSDL文档后,右键另存为成XML文件。
MobileCodeWS.xml
3、iOS可以通过wsdl2objc工具,来生成对应的调用web service服务的接口。
也就是利用 wsdl2objc 这个工具直接转换为OC类。
wsdl2objc源码可以通过下面地址获取。
https://github.com/vodaion/wsdl2objc
4、编译运行wsdl2objc
1)项目run后。
第一个为WebService的地址 第二个为生成的OC类存放的位置 然后点击Parse WSDL 就OK了 。
2)这时候会发现,转换失败。项目需要做一些修改。
找到下面这个目录。
/Users/wugl/Library/Application Support/
在里面添加一个目录wsdl2objc
接着在项目工程中找到那些.template文件,将他们都copy到创建的wsdl2objc文件夹里面。
另外,将WSDL的输入路径通过代码写死。
通过上面的两步修改之后,就可以成功生成对应的OC代码了。
2)将生成的类直接拖入工程就可以用了
3)生成的文件一般为MRC 需要转为ARC
4)编译出错: “libxml/tree.h” file not found
解决方法 :
TARGETS->Build Settings->Linking->Other Linker Flags 设置"-lxml2"
TARGETS->Build Settings->Search Paths->Header Search Paths 设置"/usr/include/libxml2"
TARGETS -> Build Phases -> Link Binary With Libraries,添加CFNetwork.framework
4、代码:
#import "MobileCodeWS.h"
MobileCodeWS_getMobileCodeInfo *req = [[MobileCodeWS_getMobileCodeInfo alloc] init];
req.mobileCode = @"13668969753";
MobileCodeWSSoapBinding *info = [[MobileCodeWSSoapBinding alloc] initWithAddress:@"http://ws.webxml.com.cn/WebServices/MobileCodeWS.asmx"];
[info getMobileCodeInfoAsyncUsingParameters:req delegate:(id<MobileCodeWSSoapBindingResponseDelegate>)self];
- (void)operation:(MobileCodeWSSoapBindingOperation *)operation completedWithResponse:(MobileCodeWSSoapBindingResponse *)response
NSLog(@"");
5、通过模板的方式导出OC类文件
这些模板文件,基本上是作为苹果公司网页4.1软件的输出模板文件中的文本文件。
这些.template文本文件包含有关页面布局元素和苹果的页面输出文档的格式属性。
用户可以通过创建一个新的文本文档,使用相同的布局元素和文本格式的属性,比以前的文本文档创建更快,更容易。
.template文件,包括那些确切的页面布局和文本格式的元素,而不是从头开始创建的文本文档。
6、通过wsdl2objc工具来生成对应web service的objective-c 类。
这个类做了几件很重要的事情:
1)对SOAP协议的XML请求数据进行封装;
2)对web service服务器返回的数据进行XML解析;
3)内部封装了网络请求NSURLConnection
其JAVA后台大概是这个样子
public getMobileCodeInfo (@WebParam(name=“mobileCode” , name=“userID”) String mobileCode, String userID)
7、代码如下:
//请求:
NSString *soapStr = [NSString stringWithFormat:@"<?xml version=\\"1.0\\" encoding=\\"utf-8\\"?>\\
<soap:Envelope xmlns:xsi=\\"http://www.w3.org/2001/XMLSchema-instance\\" xmlns:xsd=\\"http://www.w3.org/2001/XMLSchema\\"\\
xmlns:xsl=\\"http://www.w3.org/1999/XSL/Transform\\"\\
xmlns:MobileCodeWS=\\"http://WebXml.com.cn/\\"\\
xmlns:soap=\\"http://schemas.xmlsoap.org/soap/envelope/\\">\\
<soap:Header>\\
</soap:Header>\\
<soap:Body>\\
<MobileCodeWS:getMobileCodeInfo>\\
<MobileCodeWS:mobileCode>13668969753</MobileCodeWS:mobileCode>\\
</MobileCodeWS:getMobileCodeInfo>\\
</soap:Body>\\
</soap:Envelope>"];
NSURL *url=[NSURL URLWithString:@"http://ws.webxml.com.cn/WebServices/MobileCodeWS.asmx"];
NSMutableURLRequest *request=[NSMutableURLRequest requestWithURL:url];
[request setHTTPMethod:@"POST"];
[request addValue:@"application/soap+xml; charset=utf-8" forHTTPHeaderField:@"Content-Type"];
[request addValue:[NSString stringWithFormat:@"%zd", soapStr.length] forHTTPHeaderField:@"Content-Length"];
[request addValue:@"http://WebXml.com.cn/getMobileCodeInfo" forHTTPHeaderField:@"SOAPAction"];
//SOAPAction字段的赋值规则是:nameSpace/methodName
[request setHTTPBody:[soapStr dataUsingEncoding:NSUTF8StringEncoding]];
NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error)
NSString *result = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(@"进入成功回调Session-----结果:%@----请求地址:%@", result, response.URL);
if (error)
NSLog(@"Session----失败----%@", error.localizedDescription);
];
[task resume];
//请求响应的数据也是一个SOAP协议的XML文档,想要获取到想要的数据,必须对SOAP协议比较了解,才能解析出对应字段的值。
六、TAF框架的介绍
TAF 是分布式基于 epoll 的多线程非阻塞的高性能且支持同步、异步、单向调用 RPC 框架。
1、TAF框架的特点和优势是什么?
框架将网络线程和业务线程隔离,并通过队列和管道实现网络线程和业务线程间通信。
框架维护网络连接,实现客户端和服务端远程调用和本地调用基本一样,用户只需关注业务逻辑。
框架支持多种语言开发,集高可用,高性能,高并发,高效率等优秀特性。
2、TAF框架使用的是什么协议?
框架协议层使用适宜传输且与语言无关的JCE、WUP协议;
传输层提供完善网络通信机制,包括RPC;taf框架是基于epoll的多线程非阻塞RPC框架;主要实现网络线程和业务线程隔离;
(框架实现底层网络线程,框架维护网络连接队列,数据接收队列,数据发送队列,通过pipe实现网络线程和业务线程间通信,业务侧只需要考虑业务线程处理业务逻辑,很大程度提升业务开发效率)
提问:
怎么理解这个WUP协议?
回答:
WUP协议包体的构建相对简单,采取已有的jar包即可进行组包,解包。
协议结构中,有一个协议头,协议包体,一个服务器字段servername,一个业务命令字字段funcname,一个requestId。
通过servername,客户端可以将包体透传到该业务服务器,通过funcname,业务服务器会调用相应的解包结构体来进行解包操作。
3、Web Service和TAF框架有哪些类似的思想?
1)TAF:基于JCE编码的协议层封装;
Web Service:基于XML的SOAP协议封装;
2)TAF:UniPacket实现请求与回应包对象的封装, 支持协议动态扩展;
Web Service:通过一个工具生成相关平台的代码,也做到了请求和响应的序列化、反序列化(封包、解包)的封装,以及网络请求逻辑的封装;
3)序列化的数据可用于网络传输或者持久化存储;
4、网络传输的数据方面的差别
TAF:二进制数据流传输;Web Service:XML文本
1)TAF:TARS编码协议是一种数据编解码规则,它将整形、枚举值、字符串、序列、字典、自定义结构体等数据类型,
按照一定的规则编码到二进制数据流中。对端接收到二进制数据流之后,按照相应的规则反序列化可得到原始数值。
(它使用变量名作为变量的关键字,编码时,客户端将变量名打包到数据流中;解码时,对端根据变量名寻找对应的数据区,然后根据数据类型对该数据区进行反序列化得到原始数值。)
2)Web Service:
XML序列化、反序列化,http传输XML文本;
5、TAF框架的优势
性能
为优化App的网络请求速度和减小数据包大小,并配合接入层后台往C++框架改造,TAF的接入层网络数据传输协议切换成了二进制协议。
以上是关于Web Service如何实现跨平台网络通讯?的主要内容,如果未能解决你的问题,请参考以下文章