C# 中的 Onvif 事件订阅

2024-01-03

我正在用 C# 实现 ipCamera/编码器管理系统。该系统将管理来自多个供应商的多个 ipCamera 和/或编码器。使用 Onvif 代替每个 ipcamera 或编码器 sdk 将是一个好处。

管理系统的关键概念之一是监听来自摄像机的事件,例如运动检测事件。 Onvif 通过使用 ws-basenotification 或拉式支持来支持此功能。我不喜欢 pull,所以我将使用 Onvif 中的 ws-basenotification 支持(Onvif 规范 9.1)。

我已成功添加对 Sony SNC-RH164、Bosh VIP X1 XF IVA 和 Acti TCD2100 的订阅。

我的问题是:我没有从任何设备收到任何通知。任何人都可以看到我做错了什么,或者给我一些关于如何从设备获取通知的指导。 我的电脑与设备位于同一子网中。而且我的防火墙是关闭的以进行测试。

我的测试控制台应用程序启动 OnvifManager 类。

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();
        }

我的managerClass将在构造函数中初始化我的NotificationConsumer接口。

private void InitializeNotificationConsumerService()
    {
        _notificationConsumerService = new NotificationConsumerService();
        _notificationConsumerService.NewNotification += NotificationConsumerService_OnNewNotification;
        _notificationConsumerServiceHost = new ServiceHost(_notificationConsumerService);
        _notificationConsumerServiceHost.Open();
    }

我的NotificationConsumer接口实现。

 /// <summary>
/// The client reciever service for WS-BaseNotification
/// </summary>
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
public class NotificationConsumerService : NotificationConsumer
{

    public event EventHandler<EventArgs<Notify1>> NewNotification;

    /// <summary>
    /// Notifies the 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; }
}

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>

添加设备方法

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;
        }

    }

AddEventSubscription 方法

 public void AddEventSubscription(OnvifDevice onvifDevice, string initialTerminationTime = "PT2H")
    {
        if (onvifDevice.Capabilities.Events == null)
            throw new ApplicationException("The streamer info does 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 from {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;
        }
    }

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;

    }

我在使用 GrandStream 相机时遇到了这个问题。我必须使用相机 Web UI 添加一个或多个检测区域,以使其检测运动。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C# 中的 Onvif 事件订阅 的相关文章

  • STL 迭代器:前缀增量更快? [复制]

    这个问题在这里已经有答案了 可能的重复 C 中的预增量比后增量快 正确吗 如果是 为什么呢 https stackoverflow com questions 2020184 preincrement faster than postinc
  • 机器Epsilon精度差异

    我正在尝试计算 C 中双精度数和浮点数的机器 epsilon 值 作为学校作业的一部分 我在 Windows 7 64 位中使用 Cygwin 代码如下 include
  • std::list 线程push_back、front、pop_front

    std list 线程安全吗 我假设不是这样 所以我添加了自己的同步机制 我认为我有正确的术语 但我仍然遇到问题 每个函数都由单独的线程调用 Thread1 不能等待 它必须尽可能快 std list
  • 如何在 C# 中打开 Internet Explorer 属性窗口

    我正在开发一个 Windows 应用程序 我必须向用户提供一种通过打开 IE 设置窗口来更改代理设置的方法 Google Chrome 使用相同的方法 当您尝试更改 Chrome 中的代理设置时 它将打开 Internet Explorer
  • 从经典 ASP 调用 .Net C# DLL 方法

    我正在开发一个经典的 asp 项目 该项目需要将字符串发送到 DLL DLL 会将其序列化并发送到 Zebra 热敏打印机 我已经构建了我的 DLL 并使用它注册了regasm其次是 代码库这使得 IIS 能够识别它 虽然我可以设置我的对象
  • 如何连接重叠的圆圈?

    我想在视觉上连接两个重叠的圆圈 以便 becomes 我已经有部分圆的方法 但现在我需要知道每个圆的重叠角度有多大 但我不知道该怎么做 有人有主意吗 Phi ArcTan Sqrt 4 R 2 d 2 d HTH Edit 对于两个不同的半
  • 对类 static constexpr 结构的未定义引用,g++ 与 clang

    这是我的代码 a cp p struct int2 int x y struct Foo static constexpr int bar1 1 static constexpr int2 bar2 1 2 int foo1 return
  • 访问外部窗口句柄

    我当前正在处理的程序有问题 这是由于 vista Windows 7 中增强的安全性引起的 特别是 UIPI 它阻止完整性级别较低的窗口与较高完整性级别的窗口 对话 就我而言 我想告诉具有高完整性级别的窗口进入我们的应用程序 它在 XP 或
  • ASP.NET Core 3.1登录后如何获取用户信息

    我试图在登录 ASP NET Core 3 1 后获取用户信息 如姓名 电子邮件 id 等信息 这是我在登录操作中的代码 var claims new List
  • 两个静态变量同名(两个不同的文件),并在任何其他文件中 extern 其中一个

    在一个文件中将变量声明为 static 并在另一个文件中进行 extern 声明 我认为这会在链接时出现错误 因为 extern 变量不会在任何对象中看到 因为在其他文件中声明的变量带有限定符 static 但不知何故 链接器 瑞萨 没有显
  • 结构体的内存大小不同?

    为什么第一种情况不是12 测试环境 最新版本的 gcc 和 clang 64 位 Linux struct desc int parts int nr sizeof desc Output 16 struct desc int parts
  • 实例化类时重写虚拟方法

    我有一个带有一些虚函数的类 让我们假设这是其中之一 public class AClassWhatever protected virtual string DoAThingToAString string inputString retu
  • C 编程:带有数组的函数

    我正在尝试编写一个函数 该函数查找行为 4 列为 4 的二维数组中的最大值 其中二维数组填充有用户输入 我知道我的主要错误是函数中的数组 但我不确定它是什么 如果有人能够找到我出错的地方而不是编写新代码 我将不胜感激 除非我刚去南方 我的尝
  • 空指针与 int 等价

    Bjarne 在 C 编程语言 中写道 空指针与整数零不同 但 0 可以用作空指针的指针初始值设定项 这是否意味着 void voidPointer 0 int zero 0 int castPointer reinterpret cast
  • C# 动态/expando 对象的深度/嵌套/递归合并

    我需要在 C 中 合并 2 个动态对象 我在 stackexchange 上找到的所有内容仅涵盖非递归合并 但我正在寻找能够进行递归或深度合并的东西 非常类似于jQuery 的 extend obj1 obj2 http api jquer
  • 如何实例化 ODataQueryOptions

    我有一个工作 简化 ODataController用下面的方法 public class MyTypeController ODataController HttpGet EnableQuery ODataRoute myTypes pub
  • 如何在 Linq to SQL 中使用distinct 和 group by

    我正在尝试将以下 sql 转换为 Linq 2 SQL select groupId count distinct userId from processroundissueinstance group by groupId 这是我的代码
  • 为什么C++代码执行速度比java慢?

    我最近用 Java 编写了一个计算密集型算法 然后将其翻译为 C 令我惊讶的是 C 的执行速度要慢得多 我现在已经编写了一个更短的 Java 测试程序和一个相应的 C 程序 见下文 我的原始代码具有大量数组访问功能 测试代码也是如此 C 的
  • Mono 应用程序在非阻塞套接字发送时冻结

    我在 debian 9 上的 mono 下运行一个服务器应用程序 大约有 1000 2000 个客户端连接 并且应用程序经常冻结 CPU 使用率达到 100 我执行 kill QUIT pid 来获取线程堆栈转储 但它总是卡在这个位置
  • 现代编译器是否优化乘以 1 和 -1

    如果我写 template

随机推荐

  • Twitter Bootstrap 选项卡:内容窗格中的链接不起作用

    我这里有一个工作选项卡实例 并准备了一个 jsfiddle 不知何故 选项卡在这里无法正常工作 但链接问题仍然存在 http jsfiddle net Gyrga 6 http jsfiddle net Gyrga 6 选项卡窗格中的链接不
  • 二进制序列 x 位长的所有排列

    我想找到一种干净而聪明的方法 在 python 中 来查找 1 和 0 x 字符长的字符串的所有排列 理想情况下 这会很快并且不需要进行太多迭代 所以 对于 x 1 我想要 0 1 x 2 00 01 10 11 etc 现在我有这个 它很
  • 将一列拆分为多行

    谁能告诉我如何实现这个目标 在某些情况下 我的表中的列包含逗号分隔的值 如果是这样 我需要为这些值创建新行 此外 作为一个例子 一个表包含 1 行 4 列第 2 栏 第 3 栏 Col4 具有以下值 A 乙 C 分别为1 2 3 因此 Co
  • 用于重命名文件夹中的文件并再次命名的批处理文件

    恐怕这是一个有点过时的问题 但这里是 我有一个程序可以按顺序生成一些 RAW 文件 例如 示例 1 RAW示例 2 RAW 然后根据需要向数字添加额外的有效数字 例如 示例 10 RAW示例 200 RAW 我需要将这些文件名转换为数字 以
  • 在地图期间获取前一个元素的功能方法

    我有一个数组map超过 我需要将当前元素与前一个元素进行比较 我通过比较当前元素与前一个元素是否相同来检测id并根据这种情况做一些不同的事情 有没有一种纯粹的函数式方法可以在不进行索引数学的情况下做到这一点 items map item i
  • 如何在 SymPy 中创建一个参数本身就是随机变量的随机变量?

    我有一个随机变量 Y 其分布为泊松分布 参数本身就是随机变量 X 其分布为泊松分布 参数为 10 如何使用 SymPy 自动计算 X 和 Y 之间的协方差 代码 from sympy stats import x1 Poisson x1 3
  • 开玩笑:测试 window.location.reload

    我如何编写一个测试来确保该方法reloadFn实际上会重新加载窗口吗 我发现这个资源 https gist github com remarkablemark 5cb571a13a6635ab89cf2bb47dc004a3但我不清楚当窗口
  • 如何处理 JavaScript 中 setTimeout 的错误?

    简单的问题关于try catch对于函数在setTimeout try setTimeout function throw new Error error 300 catch e console log eeee console log e
  • 如何在 ListView 顶部插入小部件?

    简要说明 在我的所有代码示例中 您都会看到类似的内容material Widget而不是仅仅Widget 这是因为我喜欢这样命名我的导入 import package flutter material dart as material 我的
  • Fragment 切换期间 onResume() 的替代方案

    onResume 当我们在片段之间切换多次时 不会调用该方法 那么 有没有更好的方法来处理恢复操作呢 代码如下 Step 1 创建接口 public interface YourFragmentInterface void fragment
  • Angular4中的ActivatedRoute和ActivatedRouteSnapshot有什么区别

    有什么区别ActivatedRouteSnapshot and ActivatedRoute在 Angular 4 中 我的理解是ActivatedRouteSnapshot是一个孩子ActivatedRoute 意思是ActivatedR
  • 扩展中的延迟加载属性 (Swift)

    我知道 swift 不允许在扩展中声明存储的属性 出于同样的原因 延迟加载的属性也是被禁止的 我知道计算属性是一种选择 但我的任务应该只执行一次 是否有任何黑客 替代 被忽视的方法来模仿扩展中的惰性变量 Thanks 如果你不需要参考sel
  • requestWindowFeature(Window.FEATURE_NO_TITLE);给出例外

    import android content pm ActivityInfo import android os Bundle import android preference ListPreference import android
  • 只有我吗?我发现与 XPath 相比,LINQ to XML 有点麻烦

    我是一名 C 程序员 因此我无法利用 VB 中炫酷的 XML 语法 Dim itemList1 From item In rss
  • 如何验证 reCAPTCHA V2 Java (Servlet)

    这是一个问答风格的帖子 我将同时发布问题和答案 主要原因是我花了相当多的时间寻找验证 recaptcha V2 的最简单方法 因此 我将分享我的知识 以避免进一步浪费开发人员的时间 如何做一个服务器端验证谷歌的验证码 V2 or 隐形验证码
  • Docker构建npm安装错误网络超时

    我尝试将映像构建到节点应用程序 但是当我执行 docker build 时显示运行 npm install 时出现错误 npm 错误 网络超时时间 https registry npmjs org cookie cookie 0 4 0 t
  • 如何并行化复杂的 for 循环

    我有一个复杂的for循环 其中包含循环中对多个记录的多个操作 循环看起来像这样 for i j k in zip is js ks declare multiple lists like a b if i for items in i va
  • 正则表达式来匹配和验证互联网媒体类型?

    我想验证通过 API 输入的互联网类型 你能帮忙写一个正则表达式来匹配吗 下面的示例类型来自http en wikipedia org wiki Internet media type http en wikipedia org wiki
  • 出现错误“‘targetFramework’属性当前引用的版本高于已安装的 .NET Framework 版本”

    我在 IIS7 服务器上发布了 ASP NET Web API 当我在本地测试它时 我收到以下框架错误 配置错误 处理过程中发生错误 服务此请求所需的配置文件 请查看 具体错误详情如下并修改你的配置文件 适当地 解析器错误消息 target
  • C# 中的 Onvif 事件订阅

    我正在用 C 实现 ipCamera 编码器管理系统 该系统将管理来自多个供应商的多个 ipCamera 和 或编码器 使用 Onvif 代替每个 ipcamera 或编码器 sdk 将是一个好处 管理系统的关键概念之一是监听来自摄像机的事