ONVIF学习笔记(2)gSOAP初探

 

gSOAP 编译工具提供了一个SOAP关于C/C++ 语言的实现,从而让C/C++语言开发Web Services服务端或客户端程序的工作变得轻松了很多。甚至,即使你对Web Services不甚了解都没有关系,有了gSOAP这样的工具,你也能开发基于SOAP方式实现的Web Services客户端。

什么是 SOAP?

基本的 Web services 平台是 XML + HTTP。

  • SOAP 指简易对象访问协议
  • SOAP 是一种通信协议
  • SOAP 用于应用程序之间的通信
  • SOAP 是一种用于发送消息的格式
  • SOAP 被设计用来通过因特网进行通信
  • SOAP 独立于平台
  • SOAP 独立于语言
  • SOAP 基于 XML
  • SOAP 很简单并可扩展
  • SOAP 允许您绕过防火墙
  • SOAP 将作为 W3C 标准来发展

Why SOAP?

对于应用程序开发来说,使程序之间进行因特网通信是很重要的。

目前的应用程序通过使用远程过程调用(RPC)在诸如 DCOM 与 CORBA 等对象之间进行通信,但是 HTTP 不是为此设计的。RPC 会产生兼容性以及安全问题;防火墙和代理服务器通常会阻止此类流量。

通过 HTTP 在应用程序间通信是更好的方法,因为 HTTP 得到了所有的因特网浏览器及服务器的支持。SOAP 就是被创造出来完成这个任务的。

SOAP 提供了一种标准的方法,使得运行在不同的操作系统并使用不同的技术和编程语言的应用程序可以互相进行通信。

SOAP 构建模块

一条 SOAP 消息就是一个普通的 XML 文档,包含下列元素:

  • 必需的 Envelope 元素,可把此 XML 文档标识为一条 SOAP 消息
  • 可选的 Header 元素,包含头部信息
  • 必需的 Body 元素,包含所有的调用和响应信息
  • 可选的 Fault 元素,提供有关在处理此消息所发生错误的信息

语法规则

这里是一些重要的语法规则:

  • SOAP 消息必须用 XML 来编码
  • SOAP 消息必须使用 SOAP Envelope 命名空间
  • SOAP 消息必须使用 SOAP Encoding 命名空间
  • SOAP 消息不能包含 DTD 引用
  • SOAP 消息不能包含 XML 处理指令

SOAP 消息的基本结构





  ...
  ...



  ...
  ...
  
    ...
    ...
  


一个 SOAP 实例

在下面的例子中,一个 GetStockPrice 请求被发送到了服务器。此请求有一个 StockName 参数,而在响应中则会返回一个 Price 参数。此功能的命名空间被定义在此地址中: "http://www.example.org/stock"

SOAP 请求:

POST /InStock HTTP/1.1
Host: www.example.org
Content-Type: application/soap+xml; charset=utf-8
Content-Length: nnn




  
    
      IBM
    
  
  

 SOAP 响应:

HTTP/1.1 200 OK
Content-Type: application/soap+xml; charset=utf-8
Content-Length: nnn




  
    
      34.5
    
  
  

以上soap内容摘自http://www.w3school.com.cn/soap/index.asp

SOAP与WSDL的联系

 WSDL是服务接口,它描述了对应webservice的功能,看起来是用xml语言写成的描述函数接口的文档,而webservice实现功能述求。从外部看它就是服务提供者,没有WSDL就相当于没有服务提供者, SOAP是服务者和消费者建立的双向通信通道,服务方提供给消费方WSDL,这是两者达成的共识。SOAP是在解析并遵守WSDL文档格式基础之上开发的. 没有WSDL文档,就无法开发SOAP.SOAP是依附于HTTP协议之上的传输协议,用来建立服务方和消费方的连接,传输的数据格式是由WSDL定义的. 

一个gSOAP官网的calc客户端(C++版本)例子

首先,下载gsoap工具,解压后将下边几个文件放在一起

ONVIF学习笔记(2)gSOAP初探_第1张图片

在控制台中,进入wsdl2h.exe 的目录,执行下边的命令。这个的作用是根据WSDL文件生成calc的头文件,以便于生成cpp代码

wsdl2h -o calc.h http://www.genivia.com/calc.wsdl

如下图所示:

ONVIF学习笔记(2)gSOAP初探_第2张图片

calc.h文件包含以下声明(这里只显示了一个操作):

//gsoap ns2   schema namespace: urn:calc
//gsoap ns2   schema form:      unqualified
//gsoap ns2  service name:      calc 
//gsoap ns2  service type:      calcPortType 
//gsoap ns2  service port:      http://websrv.cs.fsu.edu/~engelen/calcserver.cgi 
//gsoap ns2  service namespace: urn:calc 
//gsoap ns2  service transport: http://schemas.xmlsoap.org/soap/http 

//gsoap ns2  service method-protocol:      add SOAP
//gsoap ns2  service method-style:         add rpc
//gsoap ns2  service method-encoding:      add http://schemas.xmlsoap.org/soap/encoding/
//gsoap ns2  service method-action:        add ""
//gsoap ns2  service method-output-action: add Response
int ns2__add(
    double a,      // Input parameter
    double b,      // Input parameter
    double &result // Output parameter
);

 

接下来继续在控制台执行如下命令:

soapcpp2 -j -CL -I/path/to/gsoap/import calc.h

作用为根据上面生成的头文件生成C++框架代码

ONVIF学习笔记(2)gSOAP初探_第3张图片

结果如上图所示。

接下来创建一个简单的控制台程序,来测试接口

// testCalc.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"

#include "calc.nsmap"      // XML namespace mapping table (only needed once at the global level)
#include "soapcalcProxy.h" // the proxy class, also #includes "soapH.h" and "soapStub.h"

int _tmain(int argc, _TCHAR* argv[])
{
    calcProxy calc;
    double sum;
    if (calc.add(1.23, 4.56, sum) == SOAP_OK)
        std::cout << "Sum = " << sum << std::endl;
    else
        calc.soap_stream_fault(std::cerr);
    calc.destroy(); // same as: soap_destroy(calc.soap); soap_end(calc.soap);
    system("pause");
	return 0;
}

我一直卡在这里很久,因为每次编译都会出现如下错误,在网上各种找答案也找不到,最后我查看了官方的zip内的例子,发现配置工程的时候,需要把文件包含进去,在编译就不会出现这类问题了。

ONVIF学习笔记(2)gSOAP初探_第4张图片

添加工程如下:

ONVIF学习笔记(2)gSOAP初探_第5张图片

之后就可以编译通过了,代码结果如下:

ONVIF学习笔记(2)gSOAP初探_第6张图片

你可能感兴趣的:(ONVIF,Onvif,协议开发记录)