主要在调测事件用例的过程中,发现了大量的信息,和未曾碰到的场景和非法错误等信息,先总结解决办法如下:

(1)测试过程中发现以前的一个难题解决了,原先在生成soap空间命名的文件中有部分需要下载,离线生成则失败,不能打开文件。其实在生成过程中wsdl增加了导入命名空间的机制,要指定本地离线文件路径即可。但有个注意的地方是,相同扩展名的文件居然可以自动推导,不用加相对路径,增加反而出错。

(2)熟读typemap.dat定义自生成的文件,发现xsd:duration类型文件放开的是类型LONG64,这样导致测试用例时发现client发送的实际时string类型,根本走不通,所以需要屏蔽该类型定义,同时删除duration.c的编译,就会恢复string类型的处理。

(3)事件服务功能接口有基本订阅和拉点订阅,还有暂停订阅等管理,这些接口存在相互重合的地方,只能保留一个,否则订阅请求过来,几个服务都会接收并处理,这样就会有多条相应消息回复给客户端,那么客户端会直接报错。

(4)Gsoap生成的框架比较死,不能直接使用,需要修改,比如所有客户端的请求消息都是放在header中以request的路径出现,但是框架响应的时候原封不动返回request,实际上是需要返回Response,否则客户端会报错。自己封装一个共同接口实现修改返回响应去处理。

(5)旧版和新版onvif协议变化很大,有些定义的命名空间网上搜索url都是空白,已经不用了,所以根本通不过,自己追踪查找才发现挪到另外的命名空间地址中了,有的已经合并成新的地址空间,需要去寻找才能对应上,没有可一目了然的地方,需要仔细查找,比较耗时。

(6)Onvif里面处理的基本都是utc+0的时间,所以不能直接当本地时间处理,但是设备的time时间系统函数中缺少mkgmtime的接口,无法直接转换iso8601的utc时间,所以自己封装了个接口单独处理utc时间的转换,比较奏效。

(7)topic命名空间找不到,无法添加到soap namespace中。

实在添加不上名字空间,不过找到了一些信息,就是gsoap名字空间有不一样的,有的维护多张映射表nsmap,然后动态选择某个名字空间表,为了避免一张表过大,然后也是有动态获取某个名字空间来set名字空间的,和张俊商讨后采用此方法,追加error和topic的名字空间函数放到ServiceContext中作为接口,需要的地方直接ctx->patch_ns加上,结果测试成功。其实客户端也不可能打开每个名字空间地址去爬虫一样搜索有没有那个信息,也只是验证名字前缀是否包含在xmlns当中,但这只是想想,后来在w3c协议文档中看到有三个参数设定,就是strict,lax和skip,客户端针对不同类型会做判别。

(8)如果拉点订阅中带有如下信息:

<tev:SubscriptionReference xmlns:tev="http://www.onvif.org/ver10/events/wsdl">
 <wsa5:Address xmlns:wsa5="http://www.w3.org/2005/08/addressing">http://192.168.5.106:80/onvif/eventing_service?id=urn:uuid:834c5a9a-b936-7965-07d4-8c37214e9c62</wsa5:Address> <wsa5:ReferenceParameters xmlns:wsa5="http://www.w3.org/2005/08/addressing">
 <SubscriptionId xmlns="urn:schemas-pelco-com:ws:addressing:1">urn:uuid:834c5a9a-b936-7965-07d4-8c37214e9c62</SubscriptionId> 
</wsa5:ReferenceParameters>
 </tev:SubscriptionReference>


请记住每个供应商都不一样,所以,需要pullmessage是放到header中,如果有security的认证信息,情报站security信息在header的最后,同时address放到action中,referenceparameters中的subscriptionid直接放到header中。

(9)创建拉点订阅的终止时间响应,到点没有进一步拉取将结束拉点;拉取消息的终止时间一致;拉取支持至少一分钟的超时等待,没有返回空msg,有就返回。单进程单线程处理会阻塞,而拉取消息特殊有个超时等待的过程,很显然不能阻挡其他消息处理,所以单独处理创建线程去处理,现在这种线程处理方式有弊端,虽然创建处理完消息后会释放退出,但是动态创建过多线程本身也是一种资源消耗,目前先实现功能,日后可以优化,比如单线程处理队列方式等。