在onvif协议对接中,首先要明确服务器和客户端的身份

服务器:通常是你要对接的其他厂家的数字摄像头(IPC)
客户端:通常是对接的ipc的设备程序,安防业内多称(NVR),当然其他软件工具也可称为客户端,如ONVIF Device Test Tool, vlc软件

设备搜索

要访问一个IPC摄像头,或者说要调用IPC摄像头提供的Web服务接口,就要先知道其IP地址,这就是设备发现的过程,或者叫设备搜索的过程。ONVIF并未自己定义服务发现框架,而是复用了已经很成熟的WS-Discovery标准

WS-Discovery原理

WS-Discovery:全称Web Services Dynamic Discovery。
官方技术规范:http://docs.oasis-open.org/ws-dd/discovery/1.1/os/wsdd-discovery-1.1-spec-os.html

传统的Web Services服务调用的模式都是这样的:客户端在设计时就预先知道目标服务的地址(IP地址或者域名),客户端基于这个地址进行服务调用。那如果客户端预先不知道目标服务的地址该怎么办
就需要使用WS-Discovery标准,遵循该标准,客户端预先不知道目标服务地址的情况下,可以动态地探测到可用的目标服务,以便进行服务调用。这个过程就是设备发现的过程。

WS-Discovery定义了两种模式:Ad hoc模式和Managed模式。

①:Ad hoc模式客户端以多播(multicast)的形式往多播组(multicast group)发送一个Probe(探测)消息搜索目标服务,在该探测消息中,包含相应的搜寻条件。如果目标服务满足该条件,则直接将响应ProbeMatch消息(服务自身相关的信息,包括地址)回复给客户端。
②:Managed模式:即代理模式。Ad hoc模式有个局限性,只能局限于一个较小的网络。Managed模式就是为了解决这个问题的,在Managed模式下,一个维护所有可用目标服务的中心发现代理(Discovery Proxy)被建立起来,客户端只需要将探测消息发送到该发现代理就可以得到相应的目标服务信息。

Ad hoc模式,端口3702
/* 搜索请求 */
<?xml version="1.0" encoding="utf-8"?>
<Envelope 
	xmlns:tds="http://www.onvif.org/ver10/device/wsdl" 
	xmlns="http://www.w3.org/2003/05/soap-envelope">
<Header>
	<wsa:MessageID 
	xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing">
	uuid:941c75c0-2496-4ad5-ab68-bf4540192247	//和回应的RelatesTo字段值相同
	</wsa:MessageID>
	
	<wsa:To 
	xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing">
	urn:schemas-xmlsoap-org:ws:2005:04:discovery
	</wsa:To>
	
	<wsa:Action 
	xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing">
	http://schemas.xmlsoap.org/ws/2005/04/discovery/Probe
	</wsa:Action>
</Header>
<Body>
	<Probe 
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
	xmlns="http://schemas.xmlsoap.org/ws/2005/04/discovery">
	<Types>tds:Device</Types>
	<Scopes />
	</Probe>
</Body>
</Envelope>
/* 搜索回应 */
<?xml version="1.0" encoding="UTF-8"?>
<s:Envelope 
	xmlns:s="http://www.w3.org/2003/05/soap-envelope" 
	xmlns:enc="http://www.w3.org/2003/05/soap-encoding"
	mlns:xs="http://www.w3.org/2001/XMLSchema" 
	xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" 
	xmlns:wsa5="http://www.w3.org/2005/08/addressing" 
	xmlns:d="http://schemas.xmlsoap.org/ws/2005/04/discovery" 
	xmlns:dn="http://www.onvif.org/ver10/network/wsdl" 
	xmlns:tt="http://www.onvif.org/ver10/schema" 
	xmlns:tds="http://www.onvif.org/ver10/device/wsdl">
<s:Header>
	<wsa:MessageID>
	uuid:6219a33f-9802-d1a8-07bd-00:05:50:53:00:64	//设备的MAC地址
	</wsa:MessageID>
	<wsa:RelatesTo>
	uuid:941c75c0-2496-4ad5-ab68-bf4540192247	//和请求的MessageID的uuid相同
	</wsa:RelatesTo>
	<wsa:To>
	http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous
	</wsa:To>
	<wsa:Action>
	http://schemas.xmlsoap.org/ws/2005/04/discovery/ProbeMatches
	</wsa:Action>
</s:Header>
<s:Body>
	<d:ProbeMatches>
	<d:ProbeMatch>
	<wsa:EndpointReference>
	<wsa:Address>
	urn:uuid:cf20f214-5566-7788-99aa-000550530064
	</wsa:Address>
	</wsa:EndpointReference>
	<d:Types>
	dn:NetworkVideoTransmitter tds:Device
	</d:Types>
	<d:Scopes>
	onvif://www.onvif.org/type/video_encoder 
	onvif://www.onvif.org/type/audio_encoder 
	onvif://www.onvif.org/hardware/IPC-model 
	onvif://www.onvif.org/location/country/china 
	onvif://www.onvif.org/name/NVT 
	onvif://www.onvif.org/Profile/Streaming 
	onvif://www.onvif.org/A1C2B3/mac/00:05:50:53:00:64 	//设备的MAC地址
	onvif://www.onvif.org/Profile/T
	</d:Scopes>
	<d:XAddrs>
	http://10.10.88.100:8899/onvif/device_service	//设备(IPC)的IP地址和ONVIF端口号
	</d:XAddrs>
	<d:MetadataVersion>1</d:MetadataVersion>
	</d:ProbeMatch>
	</d:ProbeMatches>
</s:Body>
</s:Envelope>

搜索IPC有两种搜索方式

  1. 自己实现socket编程(UDP),通过sendto往多播地址发送探测消息(Probe),再使用recvfrom接收IPC的应答消息(ProbeMatch)。
  2. 根据ONVIF标准的remotediscovery.wsdl文档,使用gSOAP工具快速生成框架代码,直接调用其生成的函数接口来搜索IPC。

从原理上来说,这两种方式归根结底是一样的,都是WS-Discovery协议。
方式1是自己写代码。
方式2是利用gSOAP快速生成代码。
组播地址为239.255.255.250(也可以自己输入IP地址和端口。如10.10.88.100),端口3702