Как обнаружить onvif-устройства в C#

Я разрабатываю приложение, которое будет проверять устройства ONVIF, подключенные к сети, для автоматического обнаружения. В соответствии со спецификацией ONVIF Core формат SOAP сообщения Probe:

 <?xml version="1.0" encoding="UTF-8"?>
<e:Envelope xmlns:e="http://www.w3.org/2003/05/soap-envelope"
xmlns:w="http://schemas.xmlsoap.org/ws/2004/08/addressing"
xmlns:d="http://schemas.xmlsoap.org/ws/2005/04/discovery"
xmlns:dn="http://www.onvif.org/ver10/network/wsdl">
<e:Header>
<w:MessageID>uuid:84ede3de-7dec-11d0-c360-f01234567890</w:MessageID>
<w:To e:mustUnderstand="true">urn:schemas-xmlsoap-org:ws:2005:04:discovery</w:To>
<w:Action
a:mustUnderstand="true">http://schemas.xmlsoap.org/ws/2005/04/discovery/Pr
obe</w:Action>
</e:Header>
<e:Body>
<d:Probe>
<d:Types>dn:NetworkVideoTransmitter</d:Types>
</d:Probe>
</e:Body>
</e:Envelope>

Как я могу отправить это сообщение в WCF, чтобы обнаружить устройство onvif?


person user1828855    schedule 16.11.2012    source источник


Ответы (1)


Просто используйте функции обнаружения веб-служб WCF. ONVIF следует тому же стандарту, что и WCF. Вам нужно будет использовать класс DiscoveryClient для отправки зонда.

Прошло некоторое время с тех пор, как я это сделал, поэтому это может быть не совсем правильно, но ваш код должен выглядеть примерно так, как показано ниже. Многоадресный зонд найдет все обнаруживаемые устройства. Вы можете определить, ответило ли ваше устройство onvif, проверив метаданные для каждого ответа в обработчике событий. Если вы по-прежнему не можете получить ответ, вероятно, проблема связана с сетью или устройством. Если вы получите ответ, вы можете уточнить критерии поиска, чтобы уведомлять только о требуемых типах.

class Program
{
    static void Main(string[] args)
    {
        var endPoint = new UdpDiscoveryEndpoint( DiscoveryVersion.WSDiscoveryApril2005 );

        var discoveryClient = new DiscoveryClient(endPoint);

        discoveryClient.FindProgressChanged += discoveryClient_FindProgressChanged;

        FindCriteria findCriteria = new FindCriteria();
        findCriteria.Duration = TimeSpan.MaxValue;
        findCriteria.MaxResults = int.MaxValue;
        // Edit: optionally specify contract type, ONVIF v1.0
        findCriteria.ContractTypeNames.Add(new XmlQualifiedName("NetworkVideoTransmitter",
            "http://www.onvif.org/ver10/network/wsdl"));

        discoveryClient.FindAsync(findCriteria);

        Console.ReadKey();
    }

    static void discoveryClient_FindProgressChanged(object sender, FindProgressChangedEventArgs e)
    {
        //Check endpoint metadata here for required types.

    }
}
person Simon Wood    schedule 16.11.2012
comment
Дорогой Саймон, я пробовал это, но не получил никакого ответа. Я запутался в этом элементе SOAP ‹d:Types›dn:NetworkVideoTransmitter‹/d:Types› Как добавить это в FindCriteria? - person user1828855; 17.11.2012
comment
Добавьте его к именам типов контрактов критериев поиска. FindCriteria.ContractTypeNames. В зависимости от версии onvif NetworkVideoTransmitter может быть указан как область действия, а не как тип. Попробуйте выполнить асинхронный поиск без критериев. Используя обратный вызов, это позволит вам проверить ответы от всех обнаруживаемых устройств, которые должны быть включены в ваше устройство onvif. Из этой информации вы сможете выполнить более целенаправленный поиск. - person Simon Wood; 17.11.2012
comment
Ура....! Я получил ответы от моего устройства ONVIF. Большое спасибо за это руководство, Саймон. - person user1828855; 23.11.2012
comment
ПРИМЕЧАНИЕ. В соответствии со спецификацией WS-Discovery ваши устройства ONVIF должны отвечать, даже если отсутствуют критерии ContractTypeNames. Цель критериев — уменьшить количество ответов, а не разрешить ответы. Однако многие устройства слишком ограничивают интерпретацию спецификации. Некоторые приложения отправляют зонды с разными критериями в надежде найти все устройства, которые им действительно нужны, игнорируя ответы от устройств, которые им на самом деле не нужны. - person Jesse Chisholm; 26.09.2014