I am trying to receive events from an ONVIF device using the Basic Notification Interface (section 9.3 of ONVIF-Core-Specification). In other words, I want to use the Notify API and not the PullPoint.

I am programming in C# with Visual Studio 2022 and have used the Add->Service Reference to generate a C# class for the various ONVIF services, including device.wsdl and event.wsdl (e.g. https://www.onvif.org/ver10/events/wsdl/event.wsdl).

The following code works and subscribes to events with my camera, which then sends the events to <localIP>:8080/subscription-1 as expected.

 notificationProducerClient = new onvif10_event.NotificationProducerClient(binding, remoteAddress);
 notificationProducerClient.Endpoint.Address = onvifEvent.Endpoint.Address;

 var subscribe = new onvif10_event.Subscribe();
 string consumerDestAddress = string.Format("http://{0}:8080/subscription-1", localIP);
 var clientEndpoint = new onvif10_event.EndpointReferenceType() { Address = new onvif10_event.AttributedURIType() { Value = consumerDestAddress } };
 subscribe.ConsumerReference = clientEndpoint;
 subscribe.InitialTerminationTime = GetTerminationTime();

 var subscribveResponse = notificationProducerClient.Subscribe(subscribe);

 // Store the subscription URI for use in Renew
 subsribeRenewUri = subscribveResponse.SubscriptionReference.Address.Value;
 System.TimeSpan? actualTerminationDuration = subscribveResponse.TerminationTime - subscribveResponse.CurrentTime;
 subscriptionTerminationTime = (System.TimeSpan)actualTerminationDuration; // update our original termination time with what the server actually does
 renewIntervalMs = (int)(subscriptionTerminationTime.TotalMilliseconds / 2);

 subscriptionManagerClient = new onvif10_event.SubscriptionManagerClient(binding, new EndpointAddress(new Uri(subsribeRenewUri)));
 subscriptionManagerClient.Open();

However I cannot find which class to use in the auto-generated code from the event.wsdl to receive to receive the events. I have implemented my own HTTP server and I am able to receive the events from my camere.

According to the spec I think it should a NotificationConsumer class which should receive the events. Such class was auto-generated, but I do not understand from its API how to use it. Below the code that was auto-generated for this class.

    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
    [System.ServiceModel.ServiceContractAttribute(Namespace="http://docs.oasis-open.org/wsn/bw-2", ConfigurationName="onvif10_event.NotificationConsumer")]
    public interface NotificationConsumer {
        
        // CODEGEN: Generating message contract since the operation Notify is neither RPC nor document wrapped.
        [System.ServiceModel.OperationContractAttribute(IsOneWay=true, Action="http://docs.oasis-open.org/wsn/bw-2/NotificationConsumer/Notify")]
        [System.ServiceModel.XmlSerializerFormatAttribute(SupportFaults=true)]
        void Notify(Onvif.Services.onvif10_event.Notify1 request);
        
        [System.ServiceModel.OperationContractAttribute(IsOneWay=true, Action="http://docs.oasis-open.org/wsn/bw-2/NotificationConsumer/Notify")]
        System.Threading.Tasks.Task NotifyAsync(Onvif.Services.onvif10_event.Notify1 request);
    }

As you can see, it has a Notify() function that returns nothing. So looks to me more like the API a server would use to notify a client.

What am I missing? Is it possible to use the auto-generated code to receive event? Or do I need to implement my own HTTP server to receive the events?

0

There are 0 best solutions below