C# ONVIF摄像机未抛出的事件

C# ONVIF摄像机未抛出的事件,c#,events,onvif,C#,Events,Onvif,我有几个符合ONVIF标准的摄像头和编码器,我希望从中接收事件,例如运动警报 到目前为止,我设法订阅了事件wsdl,但从未抛出任何事件。我检查了设备中的设置,以确保它使用运动检测,并且当存在运动时,我可以听到继电器翻转,因此设置是正确的 我用它作为我尝试的参考,但因为它没有被接受,我会再问一次 下面是我如何设置wsdl文件的: ServicePointManager.Expect100Continue = false; EndpointAddress endPointAddress = new

我有几个符合ONVIF标准的摄像头和编码器,我希望从中接收事件,例如运动警报

到目前为止,我设法订阅了事件wsdl,但从未抛出任何事件。我检查了设备中的设置,以确保它使用运动检测,并且当存在运动时,我可以听到继电器翻转,因此设置是正确的

我用它作为我尝试的参考,但因为它没有被接受,我会再问一次

下面是我如何设置wsdl文件的:

ServicePointManager.Expect100Continue = false;
EndpointAddress endPointAddress = new EndpointAddress("http://" + CameraInformation.IpAddress + "/onvif/device_service");
HttpTransportBindingElement httpTransportBinding = new HttpTransportBindingElement { AuthenticationScheme = AuthenticationSchemes.Digest };
httpTransportBinding.KeepAliveEnabled = true;
TextMessageEncodingBindingElement textMessageEncodingBinding = new TextMessageEncodingBindingElement { MessageVersion = MessageVersion.CreateVersion(EnvelopeVersion.Soap12, AddressingVersion.WSAddressing10) };
PasswordDigestBehavior passwordDigestBehavior = new PasswordDigestBehavior(CameraInformation.Username, CameraInformation.Password);

CustomBinding customBinding = new CustomBinding(textMessageEncodingBinding, httpTransportBinding);
customBinding.SendTimeout = new TimeSpan(0, 0, 10);
以下是我初始化消费者服务的方式:

_notificationConsumerService = new NotificationConsumerService();
_notificationConsumerService.NewNotification += _notificationConsumerService_NewNotification;
_notificationConsumerServiceHost = new ServiceHost(_notificationConsumerService, new Uri("http://localhost:8085/NotificationConsumerService"));
_notificationConsumerServiceHost.Open();
NotificationConsumerService类:

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Single, AddressFilterMode = AddressFilterMode.Any)]
public class NotificationConsumerService : OnvifEvents.NotificationConsumer
{
      public event EventHandler<EventArgs<OnvifEvents.Notify1>> NewNotification;

      public void Notify(OnvifEvents.Notify1 request)
      {
          var threadSafeEventHandler = NewNotification;
          if (threadSafeEventHandler != null)
              threadSafeEventHandler.Invoke(this, new EventArgs<OnvifEvents.Notify1>(request));
      }

      public Task NotifyAsync(System21.OnvifEvents.Notify1 request)
      {
         return new Task(() =>
            {
                 //return something?
            });
     }
}

     public class EventArgs<T> : EventArgs
     {
        public EventArgs(T data)
        {
            Data = data;
        }
        public T Data { get; set; }
     }
最后添加事件订阅:

if (Capabilities.Events == null)
      throw new ApplicationException("The streamer info does not support event");
try
{
       if (NotificationProducerClient == null)
            LoadNotificationProducerClient();

       var subScribe = new OnvifEvents.Subscribe()
       {
            ConsumerReference = new OnvifEvents.EndpointReferenceType
            {
                  Address = new OnvifEvents.AttributedURIType { Value = _notificationConsumerServiceHost.BaseAddresses.First().ToString() },
            }
       };
       if (!string.IsNullOrWhiteSpace(initialTerminationTime))
            subScribe.InitialTerminationTime = initialTerminationTime;

       OnvifEvents.SubscribeResponse response = NotificationProducerClient.Subscribe(subScribe);
}

Catch (FaultException ex)
{
    Console.Write(ex.ToString());
}
catch (Exception ex)
{
    Console.Write(ex.ToString());
}

相关问题中的一个可能原因是AddressingVersion在设置为WSAddressing10时设置为None,但我之前遇到过这个问题,所以这不是解决此问题的方法。

我认为中继翻转是关于红外模式,而不是运动检测。请尝试在中打开相机。它是ONVIF发现和事件订阅的开源实现。

不确定这是否相关,但只要看看这段代码,调用不应该吗

_notificationConsumerServiceHost = new ServiceHost(_notificationConsumerService, new Uri("http://localhost:8085/NotificationConsumerService"));
大概是:

_notificationConsumerServiceHost = new ServiceHost(_notificationConsumerService, new Uri("http://<RemoteIP>:8085/NotificationConsumerService"));

i、 e.本地主机可能无法解析摄像头上的主机,在这种情况下,呼叫请求会丢失。

中继翻转实际上是由运动检测触发的。设备具有可用于运动检测的输出引脚。我使用ODM来查看设备是否真的抛出事件,它确实抛出了事件。
_notificationConsumerServiceHost = new ServiceHost(_notificationConsumerService, new Uri("http://<RemoteIP>:8085/NotificationConsumerService"));