注:由于我实际开发中参考的代码主要来自于 博客园 DoubleLi,所以完整的源码我会给出原博主的链接,我在这篇文章里可能主要就是对设备搜索的流程和原博主没说明的地方详细解释。
原博主源码地址:《Onvif开发之客户端搜索篇》(http://www.cnblogs.com/lidabo/p/6604957.html)
首先,Onvif使用了 IP:239.255.255.250 / Port:3702 的组播地址。
struct __wsdd__ProbeMatches
在DoubleLi的博文中,主要的流程是:
// Each probe should have a unique MessageID to be able to match requests and responses.
/* ONVIF::Discovery */
// Send WS-Discovery Probe, collect the responses and then
// process the responses.
probematch_type probematcheslist[]={};
// Send probe. See chapter 4.3.1 for details
probe = ONVIF::DiscoverySendProbe(scopes, types);
// Wait a while for responses
while (data_available_and_not_timeout(probe.net_handle))
{
// This fetch next probe match so that we can put it into the list
// See chapter 4.3.2 for details
probematch = ONVIF::DiscoveryReadResponse(probe);
// Store info about the match, first check for duplicates
if (!in_list(probematcheslist, probematch))
{
add_to_list(probematcheslist, probematch);
}
}
// Process the responses, see chapter 5.1.3 for details.
foreach (probeMatch in probematcheslist)
{
ONVIF::ProcessMatch(probeMatch);
}
/* ONVIF::DiscoverySendProbe */
DiscoverySendProbe(scopes, types)
{
// Each probe should have a unique MessageID to be able to match
// requests and responses. We store it in the probe place holder for later checking
probe.MessageID = "uuid:" + App.uuidGenerate();
// Build probe message, we provide
// MessageID, Types and Scopes. See SOAP trace section for how
// it actually looks like.
message = App.BuildProbeMessage(probe.MessageID, types, scopes);
// Send probe to multicast address and port according to [WS-Discovery] section 2.4
probe.net_handle = App.send_multicast("239.255.255.250", 3702, message);
return probe;
}
/* ONVIF::DiscoveryReadResponse */
DiscoveryReadResponse(probe)
{
// Read response and process it.
// We need both the body and the Header:
aProbeMatches = App.ReadProbeMatches(probe.net_handle, Header);
// Check if this is a response to the probe we sent:
if (Header.RelatesTo != probe.MessageID) {
return -1;
}
// We pick what we need from the response:
probematch.types = aProbeMatches.ProbeMatch.Types;
probematch.scopes = aProbeMatches.ProbeMatch.Scopes;
// XAddrs is a space separated list of URLs to the Device service:
probematch.xaddrs = aProbeMatches.ProbeMatch.XAddrs;
probematch.metadataversion = aProbeMatches.ProbeMatch.MetadataVersion;
probematch.address = aProbeMatches.ProbeMatch.EndpointReference.Address;
return probematch;
}