对于Onvif协议,在安防视频行业的地方,谁都知道。但是网上就有onvif协议对接的方案都是使用开源的第三方库进行对接,讲解。那么问题来了,我们能不能用代码自己实现呢?答案是肯定的。而要用我们自己的代码实现onvif协议对接,其中牵扯到诸多的协议和概念,这里我大致整理一下,对自行实现Onvif协议对接者提供一个学习思路。
学习onvif之前,需要两个最基本工具:
1、ONVIF Device Test Tool 官方的onvif协议测试工具
2、wireshark 网络抓包工具
其中wireshark 大家自行去网上下载,一个通用的工具,如果你还在想工具如何使用,那么感觉行动起来,因为它是网络开发中的瑞士军刀,开发者的必备工具。如何使用ONVIF Device Test Tool可以在我的文章中了解: http://blog.csdn.net/yuanbinquan/article/details/65443898
ONVIF Device Test Tool资源下载:http://download.csdn.net/detail/yuanbinquan/9871234
onvif 协议定义的部分wsdl文档
1、http://www.onvif.org/ver10/media/wsdl
2、http://www.onvif.org/ver20/media/wsdl
等等这里有个名词:wsdl ,这里会在后续的篇幅中介绍。这两个网址直接进入,即查看。
作为一个开发者,有了开发工具和开发资料之后,那么接下来自然是学习了。学习onvif第一步也是很重要的一步,就是onvif中的概念。对于一个初学者来说,开始接触onvif的时候,很有可能被网上一大堆的各种资料弄的晕头转向。就连笔者在最开始接触onvif的时候,也有过来人给我传输资料,而这个资料就是一个2百多兆的压缩包,里面可谓是大杂烩啥都有,这些资料也没有个纲领说明主次和功能,那个内心惶惶的...... 废话不多说了,下面列举重要概念,并逐一解释。
在onvif协议对接中,首先要明确服务器和客户端的身份
服务器:通常是你要对接的其他厂家的数字摄像头(IPC)
客户端:通常是对接的ipc的设备程序,安防业内多称(NVR),当然其他软件工具也可称为客户端,如ONVIF Device Test Tool, vlc软件
明确了服务器和客服端身份之后,就是两者之间基于某种协议通信了,这里先从服务器说起。
服务器:是一个基于web server的服务器,也就是一个网页服务器。那么问题来了,一个网页服务器如何同客户端通信呢,通信时涉及到哪些知识,这就是我们对接onvif需要学习的。下面 我先把知识点列举出来,并初步介绍一下:
1、xml:可扩展标记语言,标准通用标记语言的子集,是一种用于标记电子文件使其具有结构性的标记语言。
2、http:超文本传输协议(HTTP,HyperText Transfer Protocol)是互联网上应用最为广泛的一种网络协议
3、soap:简单对象访问协议是交换数据的一种协议规范,是一种轻量的、简单的、基于XML(标准通用标记语言下的一个子集)的协议,它被设计成在WEB上交换结构化的和固化的信息
4、WS-discovery:你在预先不知道目标服务的情况下,可以动态的探测可用的服务并调用
5、wsdl:网络服务描述语言是Web Service的描述语言,它包含一系列描述某个web service的定义。这里可以通俗的理解为协议定义。
这里列举了五个重要的概念的定义,但这些协议是需要你自己去学习和认知的。不能盲目的为了实现功能和学习,一定要知其然。
这里除了WS-discovery外,其他概念都很好学习,跟着这个网站:http://www.w3school.com.cn/ 学就可以了,当然这些知识不需要你有多精通,只需要你对其有个全面的认知,就可以掉头回来学习Onvif。
客户端对接ipc第一件事,是在组网内发现可用的ipc的ip、端口,这里用到的是WS-discovery协议,当然WS-discovery协议本身又涉及到了xml,http,soap。对了这个协议是基于upd协议的广播包实现了,那么读者有需要熟悉一下udp的数据广播原理了。
获取到组网内可用的ipc的ip、端口之后就是,建立tcp链接和服务器进行通信,来获取和设置参数了。这里面涉及的协议有xml,http,soap,wsdl。
这里以获取ipc设备信息为例,对onvif对接时的参数进行详解。
#############SEND:
POST /onvif/device_service HTTP/1.1
Host: 192.168.100.125
Content-Type:application/soap+xml;charset=utf-8
Content-Length:275
#############recv ret = 1261, RECV:
HTTP/1.1 200 OK
Server: hsoap/2.8
Content-Type: application/soap+xml;charset=utf-8
Content-Length: 1132
Connection: close
其中#############SEND:代表的是客户端发送的数据,发送到服务器的。
#############recv ret = 1261, RECV:代表着客户端接收的数据,是服务器发送给客户端的。
1、可以认为是一个http协议的post指令
2、在http post指令中可以看到,指定的数据体是soap+xml格式的,也就是4。
3、http数据体长度为275
4、是一个xml文件,同时也是符合soap语法的。
5、6 部分需要讲解一下,这是soap语法的一部分。
xmlns:xml namespace,即xml 命名空间。
使用的规则为,首先定义命名空间xmlns:namespace-prefix="namespaceURI"。Android中xml中的使用是:xmlns:前缀=http://schemas.android.com/apk/res/应用程序包路径;然后使用的时候按格式:namespace-prefix(前缀):属性
如果使用xmlns,则xmlns的定义必须放在最外层开始的的标记中
当命名空间被定义之后,所有带有相同前缀的子元素都会与同一个命名空间相关联。避免XML解析器对xml解析时的发送名字冲突,这就是使用xmlns的必要性。当自定义的View有自己的属性的时候,就用到xmlns来定义一个命名空间。
服务器发送数据部分和客户端发送数据部分的基本格式相同,就不做多述,这里重点讲解一下命名空间和wsdl的理解。
前面已经讲过了xmlns的含义了,这里联合着wsdl一起讲解:xmlns:trt="http://www.onvif.org/ver10/media/wsdl",这句文本的含义,xml节点以trt开始命名的节点,它的定义需要在http://www.onvif.org/ver10/media/wsdl wsdl文档中查看,那我们看这个wsdl的部分定义是怎么样的。如下:
如果xml节点以trt开始命名的节点名为AddAudioDecoderConfiguration,那么它基本意思为添加一个音频编码器。不难理解是客户端可以发送这条指令给服务器,从而达到增加服务器音频编码器的目的,发送该指令需要输入的参数为:ProfileToken,configrationToken,然后服务器接收到这条请求指令后,会给客户端进行回复。这里对wsdl初步描述之后,对wsdl的认知就更为清晰了,它就是一个协议定义文档。
这里的wsdl文档我只找到了部分。可惜了......
在学习了前面6部分了之后,接下来就是对接onvif协议了,比如我需要一个设置osd的显示的功能,那么首先你需要http、soap、xml作为基础知识,封装最基本的数据格式,然后是在相关wsdl文档中找到设置osd显示的定义。然后填充成一个完成的数据包,发送给服务器,等待服务器应答,并处理相应的应答数据。
在"http://www.onvif.org/ver10/media/wsdl 找到设置osd的解析:
然后生成文本,由客户端发送数据:
#############SEND:
POST /onvif/device_service HTTP/1.1
Host: 192.168.100.125
Content-Type:application/soap+xml;charset=utf-8
Content-Length:584
服务器应答数据:
#############recv ret = 966, RECV:
HTTP/1.1 200 OK
Server: hsoap/2.8
Content-Type: application/soap+xml;charset=utf-8
Content-Length: 838
Connection: close
整篇文正都只是一个onvif协议对接的基本开发流程。