Onvif Event Subscription in C# -
i implementing ipcamera/encoder management system in c#. system manage multiple ipcameras and/or encoders multiple vendors. using onvif instead off each ipcamera or encoders sdk benefit.
one of key concepts of management system listen on events, such motion detection events, cameras. onvif supports use of ws-basenotification or pull type support. don’t pull, use ws-basenotification support in onvif (onvif spec 9.1).
i have added subscription sony snc-rh164, bosh vip x1 xf iva , acti tcd2100.
my problem is: don’t notifications of devices. can see i'm doing wrong or give som pointers on how notifications devices. pc on same subnet devices. , firewall turned off test.
my test console app initiating onvifmanager class.
using (var manager = new onvifmanager()) { //manager.scanfordevices(); var sonydevice = new onvifclasslib.onvifdevice { onvifdeviceserviceuri = new uri(@"http://192.168.0.101/onvif/device_service"), }; manager.adddevice(sonydevice); manager.addeventsubscription(sonydevice, "pt1h"); var boshdevice = new onvifclasslib.onvifdevice { onvifdeviceserviceuri = new uri(@"http://192.168.0.102/onvif/device_service"), }; manager.adddevice(boshdevice); manager.addeventsubscription(boshdevice, string.empty); var actidevice = new onvifclasslib.onvifdevice { onvifdeviceserviceuri = new uri(@"http://192.168.0.103/onvif/device_service"), username = "uid", password = "pwd" }; manager.adddevice(actidevice); manager.addeventsubscription(actidevice); console.writeline("waiting..."); console.read(); } my managerclass in constructor initialize notificationconsumer interface.
private void initializenotificationconsumerservice() { _notificationconsumerservice = new notificationconsumerservice(); _notificationconsumerservice.newnotification += notificationconsumerservice_onnewnotification; _notificationconsumerservicehost = new servicehost(_notificationconsumerservice); _notificationconsumerservicehost.open(); } my notificationconsumer interface implementation.
/// <summary> /// client reciever service ws-basenotification /// </summary> [servicebehavior(instancecontextmode = instancecontextmode.single)] public class notificationconsumerservice : notificationconsumer { public event eventhandler<eventargs<notify1>> newnotification; /// <summary> /// notifies specified request. /// </summary> /// <param name="request">the request.</param> /// <remarks>a </remarks> public void notify(notify1 request) { var threadsafeeventhandler = newnotification; if (threadsafeeventhandler != null) threadsafeeventhandler.invoke(this, new eventargs<notify1>(request)); } } public class eventargs<t> : eventargs { public eventargs(t data) { data = data; } public t data { get; set; } } the config notificationconsumerservice
<services> <service name="onvifclasslib.notificationconsumerservice"> <endpoint address="" binding="custombinding" bindingconfiguration="custombasichttpbinding" name="customhttpbinding" contract="eventservice.notificationconsumer" /> <host> <baseaddresses> <add baseaddress="http://192.168.0.10:8080/notificationconsumerservice" /> </baseaddresses> </host> </service> </services> <bindings> <custombinding> <binding name="custombasichttpbinding"> <textmessageencoding messageversion="soap12"> <readerquotas maxstringcontentlength="80000" /> </textmessageencoding> <httptransport maxreceivedmessagesize="800000" maxbuffersize="800000" /> </binding> </custombinding> </bindings> the adddevice method
public void adddevice(onvifdevice device) { loadcapabilities(device); onvifdevices.add(device); } internal void loadcapabilities(onvifdevice onvifdevice) { if (onvifdevice.onvifdeviceserviceuri == null) return; if (onvifdevice.deviceclient == null) loaddeviceclient(onvifdevice); try { onvifdevice.capabilities = onvifdevice.deviceclient.getcapabilities(new[] { onvifclasslib.devicemanagement.capabilitycategory.all }); } catch (exception ex) { console.write(ex.tostring()); } } private void loaddeviceclient(onvifdevice onvifdevice) { if (onvifdevice.onvifdeviceserviceuri == null) return; var serviceaddress = new endpointaddress(onvifdevice.onvifdeviceserviceuri.tostring()); var binding = getbindingfactory(onvifdevice); onvifdevice.deviceclient = new onvifclasslib.devicemanagement.deviceclient(binding, serviceaddress); if (!string.isnullorwhitespace(onvifdevice.username)) { onvifdevice.deviceclient.clientcredentials.username.username = onvifdevice.username; onvifdevice.deviceclient.clientcredentials.username.password = onvifdevice.password; } } the addeventsubscription method
public void addeventsubscription(onvifdevice onvifdevice, string initialterminationtime = "pt2h") { if (onvifdevice.capabilities.events == null) throw new applicationexception("the streamer info not support event"); try { if (onvifdevice.notificationproducerclient == null) loadnotificationproducerclient(onvifdevice); xmlelement[] filterxml = null; var subscribe = new subscribe() { consumerreference = new endpointreferencetype { address = new attributeduritype { value = _notificationconsumerservicehost.baseaddresses.first().tostring() }, } }; if (!string.isnullorwhitespace(initialterminationtime)) subscribe.initialterminationtime = initialterminationtime; onvifdevice.subscriberesponse = onvifdevice.notificationproducerclient.subscribe(subscribe); console.writeline("listening on event {0}", onvifdevice.notificationproducerclient.endpoint.address.uri.tostring()); } catch (faultexception ex) { console.write(ex.tostring()); } catch (exception ex) { console.write(ex.tostring()); } } private void loadnotificationproducerclient(onvifdevice onvifdevice) { var serviceaddress = new endpointaddress(onvifdevice.capabilities.events.xaddr.tostring()); var binding = getbindingfactory(onvifdevice); onvifdevice.notificationproducerclient = new onvifclasslib.eventservice.notificationproducerclient(binding, serviceaddress); if (!string.isnullorwhitespace(onvifdevice.username)) { onvifdevice.notificationproducerclient.clientcredentials.username.username = onvifdevice.username; onvifdevice.notificationproducerclient.clientcredentials.username.password = onvifdevice.password; } } bindings soap12
private binding getbindingfactory(onvifdevice onvifdevice) { return getcustombinding(onvifdevice); } private binding getcustombinding(onvifdevice onvifdevice) { httptransportbindingelement transportelement = new httptransportbindingelement(); if (!string.isnullorwhitespace(onvifdevice.username)) transportelement.authenticationscheme = authenticationschemes.basic; var messegeelement = new textmessageencodingbindingelement(); messegeelement.messageversion = messageversion.createversion(envelopeversion.soap12, addressingversion.none); var binding = new custombinding(messegeelement, transportelement); binding.sendtimeout = new timespan(0, 10, 0); return binding; }
i think problem is, notification consumer uses addressingversion.none, while notifications onvif device formatted according ws-addressing 1.0. try change following line of getcustombinding method:
messegeelement.messageversion = messageversion.createversion( envelopeversion.soap12, addressingversion.none); to
messegeelement.messageversion = messageversion.createversion( envelopeversion.soap12, addressingversion.wsaddressing10);
Comments
Post a Comment