ONVIF Event消息解析(How to work with gSoap)

时间:2023-01-24 23:54:00

Prepare Requirements

ONVIF Event

gSoap reference

ONVIF Specification

问题描述

Event是ONVIF核心规范中一块, 文档解释了如何基于WS-Notification框架体系来工作.但是依据Event.wsdl 生成的消息结构部分, wsdl没有给出参考标准.而是给出了一个可扩展定义的dom结点点位描述. 见下引用

        <xs:element name="PullMessagesResponse">
<xs:complexType>
<xs:sequence>
<xs:element name="CurrentTime" type="xs:dateTime">
<xs:annotation>
<xs:documentation>The date and time when the messages have been delivered by the web server to the client.</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="TerminationTime" type="xs:dateTime">
<xs:annotation>
<xs:documentation>Date time when the PullPoint will be shut down without further pull requests.</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element ref="wsnt:NotificationMessage" minOccurs="0" maxOccurs="unbounded">
<xs:annotation>
<xs:documentation>List of messages. This list shall be empty in case of a timeout.</xs:documentation>
</xs:annotation>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>

Okay, let's see the reference ="wsnt:NotificationMessage"

   <!--================== Message Helper Types  =====================-->
<xsd:complexType name="NotificationMessageHolderType">
<xsd:sequence>
<xsd:element ref="wsnt:SubscriptionReference" minOccurs="0" maxOccurs="1"/>
<xsd:element ref="wsnt:Topic" minOccurs="0" maxOccurs="1"/>
<xsd:element ref="wsnt:ProducerReference" minOccurs="0" maxOccurs="1"/>
<xsd:element name="Message">
<xsd:complexType>
<xsd:sequence>
<xsd:any namespace="##any" processContents="lax" minOccurs="1" maxOccurs="1"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
<xsd:element name="NotificationMessage" type="wsnt:NotificationMessageHolderType"/>

you see. the element Message. no defined fixture struct.

Let's do somthing to watch the right truth. this way we will see how to work with gSoap to make the soap protocol comfortable.ONVIF Event消息解析(How to work with gSoap)

执行wsdl2h生成处理头文件.

/// "http://docs.oasis-open.org/wsn/b-2":NotificationMessageHolderType is a complexType.
struct wsnt__NotificationMessageHolderType
{
/// Element reference "http://docs.oasis-open.org/wsn/b-2":SubscriptionReference.
    wsa5__EndpointReferenceType*         SubscriptionReference          0; ///< Optional element.
/// Element reference "http://docs.oasis-open.org/wsn/b-2":Topic.
    struct wsnt__TopicExpressionType*    Topic                          0; ///< Optional element.
/// Element reference "http://docs.oasis-open.org/wsn/b-2":ProducerReference.
    wsa5__EndpointReferenceType*         ProducerReference              0; ///< Optional element.
    struct _wsnt__NotificationMessageHolderType_Message
    {
/// TODO: <any namespace="##any" minOccurs="1" maxOccurs="1">
/// TODO: Schema extensibility is user-definable.
///       Consult the protocol documentation to change or insert declarations.
///       Use wsdl2h option -x to remove this element.
///       Use wsdl2h option -d for xsd__anyType DOM (soap_dom_element).
    xsd__anyType                         __any                         0; ///< Catch any element content in DOM.
    }                                    Message                        1;	///< Required element.
};

now, see it. this generation with no option specitied. 没有指定任何选项默认生成为C++的.h处理文件.

you should have to see the line

_XML                                 __any                         0; ///< Catch any element content in XML string.

每个ONVIF新手上来都会被这个字段搞迷糊. Message字段, 我们必需关注的内容.居然未被解析成可用类型的数据, 那我们依赖gSoap是为什么. 我们用它来生成.h, 进一步生成我们能调用的C/C++代码. 生成的代码量还是庞大可观的. 编译老费时间, 还需要stdsoap2.h/.c的支持, 还可能会用到gSoap/plugin中相关支持.

yes, it must be useful. 是的我们会发现gSoap带来给我很大解脱. 只要我们保持一颗乐观向上的心情, 保持上进的心态.

下面由请你把这个结构中的__any字段改成指定类型,然后我们再进入下一环节的讲述.

/// Top-level root element "http://www.onvif.org/ver10/schema":Message

/// "http://www.onvif.org/ver10/schema":Message is a complexType.
struct _tt__Message
{
/// @brief Token value pairs that triggered this message. Typically only one item is present.
/// Element Source of type "http://www.onvif.org/ver10/schema":ItemList.
    struct tt__ItemList*                 Source                         0; ///< Optional element.
/// Element Key of type "http://www.onvif.org/ver10/schema":ItemList.
    struct tt__ItemList*                 Key                            0; ///< Optional element.
/// Element Data of type "http://www.onvif.org/ver10/schema":ItemList.
    struct tt__ItemList*                 Data                           0; ///< Optional element.
/// Element Extension of type "http://www.onvif.org/ver10/schema":MessageExtension.
    struct tt__MessageExtension*         Extension                      0; ///< Optional element.
/// Attribute UtcTime of type xs:dateTime.
   @time_t                               UtcTime                        1; ///< Required attribute.
/// Attribute PropertyOperation of type "http://www.onvif.org/ver10/schema":PropertyOperation.
   @enum tt__PropertyOperation*          PropertyOperation              0; ///< Optional attribute.
/// <anyAttribute namespace="##any">
/// TODO: Schema extensibility is user-definable.
///       Consult the protocol documentation to change or insert declarations.
///       Use wsdl2h option -x to remove this attribute.
///       Use wsdl2h option -d for xsd__anyAttribute DOM (soap_dom_attribute).
   @xsd__anyAttribute                    __anyAttribute                ; ///< Store anyAttribute content in DOM soap_dom_attribute linked node structure.
};

由于我们参考阅读ONVIF事件一块的文档资料以及通过odm及wireshark工具抓包分析可了解到, 国内使用的许多IPC都基本上使用已有的事件消息结构来填充上面提到的_wsnt__NotificationMessageHolderType_Message内容, 即被解释为_tt__Message的参考结构.

好吧, 那我们就来把 那行代码改掉

_XML                                 __any;

改成

_tt__Message                  tt__Message;

为什么要这样修改,后面我们会了解,这个字段命名也是有规则的. 在生成soapC.cpp的时候,会依赖字段来生成相应的解析标签, tt__Message被soapcpp2理解为一个tt:Message的标签元素,所以他解析与序列化组装消息都会依赖这个规则.

执行soapcpp2生成C/C++使用代码.

#ifndef SOAP_TYPE__wsnt__NotificationMessageHolderType_Message
#define SOAP_TYPE__wsnt__NotificationMessageHolderType_Message (1303)
/* wsnt:NotificationMessageHolderType-Message */
struct _wsnt__NotificationMessageHolderType_Message
{
struct _tt__Message *tt__Message; /* optional element of type tt:Message */
};
#endif #ifndef SOAP_TYPE_wsnt__NotificationMessageHolderType
#define SOAP_TYPE_wsnt__NotificationMessageHolderType (1177)
/* wsnt:NotificationMessageHolderType */
struct wsnt__NotificationMessageHolderType
{
struct wsa5__EndpointReferenceType *SubscriptionReference; /* optional element of type wsa5:EndpointReferenceType */
struct wsnt__TopicExpressionType *Topic; /* optional element of type wsnt:TopicExpressionType */
struct wsa5__EndpointReferenceType *ProducerReference; /* optional element of type wsa5:EndpointReferenceType */
struct _wsnt__NotificationMessageHolderType_Message Message; /* required element of type wsnt:NotificationMessageHolderType-Message */
};
#endif

gSoap对消息解析一块生成的代码,let's look.

SOAP_FMAC3 int SOAP_FMAC4 soap_out__wsnt__NotificationMessageHolderType_Message(struct soap *soap, const char *tag, int id, const struct _wsnt__NotificationMessageHolderType_Message *a, const char *type)
{
(void)soap; (void)tag; (void)id; (void)type;
if (soap_element_begin_out(soap, tag, soap_embedded_id(soap, id, a, SOAP_TYPE__wsnt__NotificationMessageHolderType_Message), type))
return soap->error;
if (soap_out_PointerTo_tt__Message(soap, "tt:Message", -1, &a->tt__Message, ""))
return soap->error;
return soap_element_end_out(soap, tag);
} SOAP_FMAC3 struct _wsnt__NotificationMessageHolderType_Message * SOAP_FMAC4 soap_in__wsnt__NotificationMessageHolderType_Message(struct soap *soap, const char *tag, struct _wsnt__NotificationMessageHolderType_Message *a, const char *type)
{
size_t soap_flag_tt__Message = 1;
if (soap_element_begin_in(soap, tag, 0, type))
return NULL;
a = (struct _wsnt__NotificationMessageHolderType_Message *)soap_id_enter(soap, soap->id, a, SOAP_TYPE__wsnt__NotificationMessageHolderType_Message, sizeof(struct _wsnt__NotificationMessageHolderType_Message), 0, NULL, NULL, NULL);
if (!a)
return NULL;
soap_default__wsnt__NotificationMessageHolderType_Message(soap, a);
if (soap->body && !*soap->href)
{
for (;;)
{ soap->error = SOAP_TAG_MISMATCH;
if (soap_flag_tt__Message && soap->error == SOAP_TAG_MISMATCH)
if (soap_in_PointerTo_tt__Message(soap, "tt:Message", &a->tt__Message, ""))
{ soap_flag_tt__Message--;
continue;
}
if (soap->error == SOAP_TAG_MISMATCH)
soap->error = soap_ignore_element(soap);
if (soap->error == SOAP_NO_TAG)
break;
if (soap->error)
return NULL;
}
if (soap_element_end_in(soap, tag))
return NULL;
}
else
{ a = (struct _wsnt__NotificationMessageHolderType_Message *)soap_id_forward(soap, soap->href, (void*)a, 0, SOAP_TYPE__wsnt__NotificationMessageHolderType_Message, 0, sizeof(struct _wsnt__NotificationMessageHolderType_Message), 0, NULL);
if (soap->body && soap_element_end_in(soap, tag))
return NULL;
}
return a;
}

结述语

最后由我来总结性的提些问题.

  1. 请问你使用gSoap的目的是为什么?
  2. 请问你觉得gSoap是用于处理什么样事情的?
  3. 请问ONVIF是什么?

对于问题1,我想大多数人都回答是出于工作需要才用到它的. 毫不例外我也是, 而且技术决策完全不是由我们来决定的. 因为我们完全无法推断上级的意志. 但BOSS的意志是必须执行的.所以我们路途就算会艰辛一点吧.

问题2 你可能会觉得和问题1没有什么两样, 但是你只要认真思考了问题1, 也就不难醒悟到, gSoap基本是soap协议的一个库支持. 依赖于gSoap方能使们从消息的封装与解析的繁琐工作中解放出来. gSoap为我们做的事情就是帮我组装序列化好的消息以便于发送, 并且能够将解析好的消息结构提供给我们以开发者真正关系的数据型态.

问题3 Sorry. ONVIF是一个市场标准, 由几个大企业协商制定的一个访问接口标准. 不是什么高级的东西.如果我们能加入该讨论社区我们也将参考标准的制定.

any way. let's talking on the Group 251296672 by QQ.

ONVIF Event消息解析(How to work with gSoap)的更多相关文章

  1. XML消息解析&lowbar;php

    初识php——微信消息处理 <?php $test = new weixin(); $test->Message(); class weixin{ public function Mess ...

  2. 微信推送给服务器的XML消息解析-springmvc 解析xml数据流

    微信推送给服务器的XML消息解析: 可以使用request.getInputStream(); 获取输入的消息流:但是需要自己解析流: spring mvc自带解析功能: controller中: @ ...

  3. laravel框架中Job和事件event的解析

    本篇文章给大家带来的内容是关于laravel框架中Job和事件event的解析,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助. 在做项目的时候,一直对Job和Event有个疑惑.感觉两 ...

  4. Netty 中的消息解析和编解码器

    本篇内容主要梳理一下 Netty 中编解码器的逻辑和编解码器在 Netty 整个链路中的位置. 前面我们在分析 ChannelPipeline 的时候说到入站和出站事件的处理都在 pipeline 中 ...

  5. NDEF消息解析实例&lbrack;转&rsqb;

      问题:按照NDEF消息格式来解析下列Hex串? D1 02 1F 53 70 91 01 0E 54 02  65 6E 68 65 6C 6C 6F 20 77 6F  72 6C 64 51 ...

  6. CEdit 样式与消息 解析

    编辑框(Edit)控件实际上是一个简易的文本编辑器,用户可以在编辑框中输入可添加或插入文本.还有复制.粘贴.剪切.删除等编辑功能. 应用程序用CreateWindowEx创建编辑框控件时,可根据控件的 ...

  7. iOS 远程推送消息解析及逻辑处理

    关于远程推送的相关配置网上已经有足够多的教程,这里就不复述了.这里讲述当客户端收到推送消息后,应怎样对其进行相应的逻辑处理. 工程的AppDelegate.m文件里提供了如下方法: //当应用程序启动 ...

  8. javascript event 事件解析

    event对象只在事件发生的过程中才有效. event的某些属性只对特定的事件有意义.比如,fromElement 和 toElement 属性只对 onmouseover 和 onmouseout ...

  9. event&period;target解析

    event.target返回最初触发事件的DOM对象. Vue例子: main.js methods:{ fan:function(event){ console.log(event.target); ...

随机推荐

  1. jsp重定向和转发

    表单提交到servlet后,servlet进行转发之后浏览器上的url为什么还是servlet的url-pattern,但是页面内容却是跳转之后页面的内容. 研究了半天之后发现这个和转发和重定向有关系 ...

  2. CSS中不为人知Zoom属性的使用介绍&lpar;IE私有属性&rpar;

    其实Zoom属性是IE浏览器的专有属性,Firefox等浏览器不支持.它可以设置或检索对象的缩放比例.除此之外,它还有其他一些小作用,比如触发ie的hasLayout属性,清除浮动.清除margin的 ...

  3. &lbrack;Think In Java&rsqb;基础拾遗4 - 并发

    第21章节 并发 1. 定义任务 任务:任务就是一个执行线程要执行的一段代码.(在C语言中就是函数指针指向的某个地址开始的一段代码) [记忆误区]:任务不是线程,线程是用来执行任务的.即任务由线程驱动 ...

  4. 部署点评Cat监控项目&lpar;转&rpar;

    原文地址:http://www.bubuko.com/infodetail-986338.html 在项目中监控代码运行的状况,可以采用点评的Cat项目来监控整个项目,但是按照官方的文档来部署cat, ...

  5. DSP using MATLAB示例Example3&period;18

    代码: % Analog Signal Dt = 0.00005; t = -0.005:Dt:0.005; xa = exp(-1000*abs(t)); % Continuous-time Fou ...

  6. javascript对象与实例

    var person=new Object(); var person2={}; 一切都是对象 person是Object的实例, 也是对象. 第二个person2也是如此,只不过它是采用字面量的方式 ...

  7. 使用EntityFramework连接 Mysql

    原文:使用EntityFramework连接 Mysql 1,安装VS.net 插件 http://forums.mysql.com/read.php?174,601041,601041 2,安装连接 ...

  8. &equals;&equals; 和 equals&lpar;&rpar;的区别

    package com.liaojianya.chapter1; /** * This program demonstrates the difference between == and equal ...

  9. iOS开发之通知机制

    1.通知中心 每一个应用程序都有一个通知中心(NSNotificationCenter)实例,专门负责协助不同对象之间的消息通信 任何一个对象都可以向通知中心发布通知(NSNotification), ...

  10. Redis持久化persistence

    一.前言 由于Redis的数据都存放在内存中,如果没有配置持久化,redis重启后数据就全丢失了,于是需要开启redis的持久化功能,将数据保存到磁盘上,当redis重启后,可以从磁盘中恢复数据. R ...