做安防集成的朋友大概都碰过这个场面:机器装好了,图像调得挺漂亮,客户机房里的NVR却不是自家的。网线一插,在NVR的"添加通道"页面里等半天,那台摄像机要么压根不出现,要么出现了,点"添加"转三十秒圈,弹出一句"连接失败";运气好点能出图,可画面卡成幻灯片,云台点了没反应,移动侦测报了警,录像却联动不起来。打电话问原厂,对方一句"我们支持ONVIF",你再问支持哪个版本、哪个Profile、用什么鉴权方式,电话那头就开始含糊。
ONVIF全网通这件事,说到底就是把"我们支持ONVIF"这句口号落到实处的过程。它指的是在IPC侧做一套兼容层,让同一台网络摄像机在面对不同年代、不同厂家、不同实现风格的NVR时,都能完成设备发现、鉴权、取流、云台控制和事件上报这一整套动作,而不是只能在自家生态里自娱自乐。这篇文章适合三类人看:做IPC固件和协议栈的开发、跑现场做对接的实施、以及NVR侧负责兼容性测试的同行。下面我按"为什么难—怎么设计—怎么配—怎么测—怎么排"的顺序,把里面那些文档里不会写的细节摊开讲。
1. 先搞清楚:能出图和对接通,完全是两码事
1.1 ONVIF规定了什么,又刻意没规定什么
ONVIF这套规范本质是一组基于SOAP/XML的Web Service接口,跑在HTTP之上,定义了设备服务、媒体服务、云台服务、事件服务、图像服务这几大块。设备服务负责"你是谁、你有什么能力、现在几点";媒体服务负责"你有几路码流、编码参数是什么、取流地址在哪";云台服务负责转动;事件服务负责报警上报。听起来很齐整,问题恰恰出在"规范只保证接口形状,不保证行为细节"。
举个最典型的例子:规范里 GetStreamUri 只要求返回一个RTSP地址,但具体路径长什么样,规范一个字都没写。于是市面上能见到的路径五花八门,有 /onvif1、/onvif/profile1、/Streaming/Channels/101、/live/ch0、/av0_0,甚至还有带一长串query参数的。NVR厂商如果偷懒,直接把某个固定路径写死在自己的添加流程里,那就只有路径恰好匹配的IPC能出图。这类"伪ONVIF"设备在早年市场里非常多,也是"支持ONVIF却加不进去"的头号元凶。
再比如Profile。Profile S只保证H.264视频流和最基本的几项能力,Profile T才把H.265、双向音频、更丰富的元数据和高级云台动作纳入进来。一台默认出H.265的摄像机去对接只认Profile S的老NVR,NVR拿到编码配置一看是H.265,直接判定不支持,添加流程中断。用户看到的现象就是"添加失败",实际原因是编码格式不匹配。
提示:对接问题九成以上不是"协议没实现",而是"实现的行为和对方预期不一致"。排查时先问自己:对方期待我返回什么形状的数据,我实际返回了什么。
1.2 各家NVR嘴里的"ONVIF"其实是三套东西
我做过一轮统计,把市面上常见的NVR按ONVIF实现风格分一下类,基本能归成三档。
第一档是"标准派",严格按照规范走完整的握手链路:WS-Discovery发现设备,GetSystemDateAndTime校时,GetCapabilities或GetServices探能力,GetProfiles拿配置,GetStreamUri取流,全程用WS-UsernameToken Digest鉴权。这类NVR对IPC的要求最高,任何一个环节返回的XML命名空间或字段格式不对,它就直接放弃。
第二档是"跳步派",为了加快添加速度,发现设备后跳过GetCapabilities,直接拿一个写死的profile token(通常是"profile0"或者"Profile_1")去调GetStreamUri。如果你的IPC返回的token叫"profile_1"或者"MainStream",它就取不到流。这类NVR在中小项目里占比很高,是最容易踩坑的一档。
第三档是"半私有派",ONVIF只是用来发现设备,真正取流走的是自家私有协议或者固定的RTSP规则,甚至要求IPC的HTTP管理端口必须是80、RTSP必须是554、用户名必须叫admin。这类设备你对它讲规范没意义,只能摸清它的脾气,做行为适配。
所以"全网通"这三个字,本质上不是把ONVIF实现得更标准,而是把这三档NVR的预期都覆盖到。这是个工程问题,不是学术问题。
2. 全网通方案的架构拆解:兼容层放在哪一层最划算
2.1 一套服务、多套行为的整体设计取舍
常见的做法有两种。一种是做多个独立的ONVIF服务实例,按端口或按路径区分,对接不同NVR时手动切换;另一种是单实例、内部做行为分支,通过配置项或自动识别切换工作模式。前者实现简单但现场配置麻烦,客户不会用;后者开发成本高但交付体验好。我们最后选的是后者,因为对接场景里最忌讳的就是"让现场实施去理解协议差异",他只需要一个开关。
内部结构上,我把兼容层切成了五个可独立开关的模块:发现模块、鉴权模块、能力声明模块、媒体协商模块、事件与云台模块。每个模块都有"标准模式"和若干"兼容模式"。配置界面上只暴露一个下拉框,叫"ONVIF兼容模式",选项是"通用/自动"加几个典型模式的代号,默认自动。自动模式的判断依据有两条:一是WS-Discovery Probe报文里的Scopes和Types特征,二是后续HTTP请求的User-Agent和SOAPAction的拼写习惯。这两条组合起来,识别准确率能到八成以上,剩下两成交给现场手动指定。
这个设计的好处是,固件只有一份,出厂默认自动,遇到识别不出来的再人工兜底。坏处是内部状态机变复杂了,测试用例数量翻了好几倍,后面讲测试的时候会提到怎么用矩阵法控制成本。
2.2 设备发现:组播地址没填对,一切免谈
设备发现走的是WS-Discovery,组播地址239.255.255.250,端口3702,NVR发Probe,IPC回ProbeMatch。这里面最容易被忽略的是XAddrs字段——它告诉NVR"来这个地址找我"。如果IPC是双网口,或者现场有多个VLAN,XAddrs里回填的可能是NVR根本路由不到的那个网口地址,于是NVR发现得到设备,添加却永远超时。
我在一个项目里被这个问题折磨了整整两天。现象特别迷惑:用笔记本接在IPC同一个交换机上,能发现能添加;接在NVR那侧就死活加不进去。后来抓包才看明白,Probe是从NVR所在的网段来的,IPC回复的XAddrs却是另一张网卡的IP。解决方式有两种,简单的是加一个"发现响应网卡绑定"配置,让IPC根据收到的Probe源地址,从路由表里选出对应的本地地址回填;复杂一点的是把XAddrs列表全部回填,让NVR自己挑。我们最后两种都做了,优先用路由匹配,匹配不到再全量返回。
另外一个细节是ProbeMatch里的Types必须包含 dn:NetworkVideoTransmitter,Scopes里建议带上 onvif://www.onvif.org/type/video_encoder 和 name、hardware 之类的条目。有些NVR靠Scopes里的name字段来显示设备名称,不带的话添加列表里就是一串IP,实施人员根本分不清哪台是哪台,这在几十路的大项目里是灾难。
注意:现场的交换机和AP如果开了组播抑制或者IGMP Snooping没配好,Probe包会被直接丢掉。排查"发现不了设备"之前,先用抓包工具确认IPC到底有没有收到Probe,别一上来就怀疑固件。
2.3 鉴权:WS-UsernameToken和HTTP Digest的分岔路
ONVIF的鉴权方式至少有四种在实战中出现:WS-UsernameToken的PasswordDigest、WS-UsernameToken的PasswordText、HTTP Digest、HTTP Basic。规范推荐Digest,但很多老NVR只实现了PasswordText,还有一部分干脆用HTTP层的鉴权。
Digest的计算方式是 Base64(SHA1(nonce字节 + created字符串 + 明文密码)),其中nonce是随机数再做Base64,created是UTC时间戳,格式必须带Z。这里有两个坑。第一个坑是时间戳校验窗口,大部分设备允许前后5分钟的偏差,如果IPC的RTC不准或者时区处理错了,NVR算出来的摘要和IPC算出来的对不上,直接返回401,现象就是"用户名密码明明是对的,就是加不进去"。第二个坑是密码里的特殊字符,某些NVR在做XML转义时处理不规范,密码里带 & 或者 < 就会解析失败。
我们的兼容层做法是三条腿走路:同时支持Digest和PasswordText两种UsernameToken,同时支持HTTP Digest;把时间戳校验窗口从5分钟放宽到可配置,默认10分钟;对XML里的密码字段做严格的实体转义。另外专门加了一条保护——当检测到连续多次鉴权失败且用户名密码正确时,在日志里打出"疑似时间偏差过大"的明确提示,而不是只记一个401。这条日志后来在现场救了无数次命。
2.4 媒体协商:Profile token、编码格式与传输模式
媒体这块的兼容点是三个:token命名、编码格式、传输模式。
token命名的问题前面说过,有些NVR写死了profile0。我们的做法是让GetProfiles至少返回三个profile,token分别叫profile0、profile1、profile2,同时在GetVideoEncoderConfigurations里也保持一致。profile0对应主码流,profile1对应子码流,profile2对应第三码流。这样无论NVR认哪个名字,都能拿到一路能用的流。听起来有点土,但确实管用。
编码格式的问题更实际。全网通模式默认要把H.265降级成H.264,因为大量存量NVR不支持H.265。降级不是简单改个字段,分辨率、帧率、GOP、码率都要跟着调整,否则NVR拿到一个"H.264 4000x3000"的配置一样会懵。我的经验值是:全网通模式下的默认主码流给1920×1080、25帧、GOP 50、CBR 4Mbps,子码流给704×576、25帧、GOP 50、CBR 1Mbps。这个参数几乎所有NVR都能吃下,出图质量也够验收。
传输模式这块,GetStreamUri返回的地址里可以带 ?transportmode=RTP-Unicast&profile=... 这样的参数。有些NVR只认RTP over TCP,有些默认UDP,跨网段或者有防火墙的环境下UDP丢包会导致花屏。全网通模式下我建议把两种模式都通过GetStreamUri暴露出来,让NVR自己选,同时在IPC侧把RTSP服务的TCP和UDP通道都开好。
2.5 云台与事件:最容易被"能出图"掩盖的功能
很多对接测试到"能看到画面"就结束了,云台和事件根本没测。等验收的时候客户一点云台,转不动;一配报警,不联动,才发现问题。
云台的核心差异在速度参数。ONVIF的ContinuousMove里速度是-1到1的浮点数,有些NVR发的是0到100的整数,IPC收到0.5和收到50,行为完全不同。兼容层要做归一化:检测到数值绝对值大于1,就按百分比处理,除以100再夹到-1到1之间。另外AbsoluteMove的坐标系也有差异,有的NVR发归一化坐标(0到1),有的发像素坐标,需要根据设备能力声明里的TranslationSpace来判断。
事件上报走的是WS-Notification的PullPoint机制,NVR先CreatePullPointSubscription,然后定期去PullMessages。有些NVR不实现完整订阅流程,只用最简单的方式轮询,或者干脆只看IPC有没有主动推送。兼容层里我建议实现两条路:完整的PullPoint订阅,以及一个简化的"事件属性"返回,让能力弱的NVR至少能读到移动侦测状态。事件的topic命名也要注意,移动侦测用 tns1:RuleEngine/CellMotionDetector/Motion 是通用度最高的,别自己造一个私有名字。
3. IPC侧落地的实操配置:一步一步来
3.1 基础网络与ONVIF服务开关
先把地基打牢。IPC接入现场网络后,第一时间确认三件事:IP地址是否和NVR同网段或者路由可达、HTTP端口是否被占用或改过、ONVIF服务是否真的在监听。
很多机型为了安全会把ONVIF服务默认关掉,或者把HTTP端口从80改成8080,而某些NVR只会去连80端口。这两件事叠加,现象就是"设备在线但加不进去"。我的做法是:出厂默认开启ONVIF,HTTP端口保持80,如果需要改端口,界面上给一个明确提示"修改后部分NVR可能无法添加"。
验证服务是否真的起来了,用最简单的curl就行,不带任何鉴权先探一下:
curl -s -i -X POST http://192.168.1.64/onvif/device_service \ -H 'Content-Type: application/soap+xml; charset=utf-8' \ -d '<?xml version="1.0" encoding="UTF-8"?> <s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope"> <s:Body xmlns:tds="http://www.onvif.org/ver10/device/wsdl"> <tds:GetSystemDateAndTime/> </s:Body> </s:Envelope>'GetSystemDateAndTime是规范里少数允许匿名调用的方法,正常应该返回200加一段UTCTime。如果连这个都返回404,说明服务路径不对,先解决路径映射再谈别的。返回值里DateTimeType必须是Manual或者NTP,UTCTime必须带Z后缀,TimeZone最好也带上。我见过有固件把本地时间当UTC返回,还不带Z,结果NVR算出来的摘要时间戳差了八小时,怎么加都加不上。
3.2 用户鉴权与时间同步的细节处理
时间同步这件事,建议在IPC上做两件事:一是支持NTP客户端,二是在ONVIF设备服务里正确响应SetSystemDateAndTime。有些NVR添加设备时会主动下发校时,如果IPC拒绝或者返回错误,NVR会认为设备异常。
用户权限方面,ONVIF规范里有Administrator、Operator、User、Anonymous几个级别。全网通场景下建议至少留一个Administrator账号,同时把匿名访问关掉——但要注意,个别老NVR在做发现和初始探测时用的是匿名请求,如果IPC对匿名请求一律返回401,它可能连设备信息都读不到就直接判定失败。折中方案是允许匿名调用GetSystemDateAndTime、GetCapabilities、GetServices、GetDeviceInformation这几个只读方法,其余全部要求鉴权。
实际操作里我还建议单独建一个ONVIF专用账号,密码用纯字母数字,长度8到16位,别用带特殊符号的强密码。这不是偷懒,是规避各家NVR在XML转义和URL编码上的实现差异。等对接稳定了,再考虑换复杂密码。
3.3 码流参数的实操配置表
全网通模式下,我一般会把三路码流按下面这个表配好,这套参数在实测中兼容性最好:
| 码流 | 分辨率 | 帧率 | 编码 | 码率控制 | 码率 | GOP | 音频 |
|---|---|---|---|---|---|---|---|
| 主码流 | 1920×1080 | 25 | H.264 High | CBR | 4096 kbps | 50 | G.711A |
| 子码流 | 704×576 | 25 | H.264 Main | CBR | 1024 kbps | 50 | 关闭 |
| 第三码流 | 640×360 | 15 | H.264 Baseline | CBR | 512 kbps | 30 | 关闭 |
几个参数的选择逻辑说一下。GOP设50,是因为25帧下两秒一个I帧,NVR做录像切片和回放定位时比较友好,GOP太长会导致回放拖动卡顿,太短则码率虚高。码率控制用CBR不用VBR,因为部分NVR的带宽预算模块只认CBR,VBR的峰值码率会被判定超限。编码档次主码流用High,兼容性略差于Main,但1080P下画质优势明显;如果对接方明确是老设备,直接降到Main更稳。音频统一用G.711A,这是兼容性最好的音频编码,AAC在不少老NVR上直接不支持。
子码流一定要开,而且必须能被GetProfiles返回。很多NVR的多画面预览走的是子码流,如果IPC只提供主码流,四画面以上就会卡顿甚至黑屏。
3.4 RTSP服务与取流地址的兼容策略
RTSP服务的配置要点有三个:端口、路径、并发数。
端口默认554,如果现场有冲突要改,改完记得让GetStreamUri返回带端口的完整地址,别只返回路径。路径方面,全网通模式建议同时支持多套别名,比如 /onvif1、/onvif/profile0、/live/ch0 都指向主码流,这样即使NVR写死了路径也能命中。当然这套别名只对ONVIF会话生效,不影响正常取流。
并发数是个隐形坑。有些IPC的RTSP服务最多支持4路并发,一个NVR可能同时拉主码流做录像、拉子码流做预览、再拉一路给客户端,很容易超限。超限之后新连接被拒绝,现象就是"NVR上能看到画面,但客户端打不开"或者"隔一段时间就断一次"。全网通模式下建议把并发上限调到8到10路,同时在日志里记录连接数和来源IP,方便排查。
验证取流最直接的方式是用播放器打开GetStreamUri返回的地址,看能不能出图、延迟多少、有没有花屏。这一步别偷懒,很多问题在NVR侧排查半天,其实是RTSP地址本身就取不到流。
4. 和各家NVR对接的实测流程
4.1 添加通道的完整链路和每一步的观察点
标准添加流程是六步,每一步都有对应的观察点,出问题时按顺序定位,比盲目猜测高效得多。
第一步,NVR发组播Probe,IPC回ProbeMatch。观察点:NVR的添加页面能不能列出设备。列不出,问题在发现层,查组播、查XAddrs。
第二步,NVR调GetSystemDateAndTime。观察点:IPC返回的时间格式对不对、有没有Z后缀。这一步失败,后面的鉴权必然失败。
第三步,NVR调GetCapabilities或GetServices。观察点:返回的XML命名空间是不是ver10,能力列表里有没有声明Media和PTZ。有些NVR会严格校验返回的能力项,多返回或漏返回都可能出问题。
第四步,NVR调GetProfiles拿配置。观察点:返回了几个profile、token叫什么、编码是不是H.264。这一步是"添加失败"的高发区。
第五步,NVR调GetStreamUri取流。观察点:返回的地址能不能被播放器打开。
第六步,NVR用返回的地址拉RTSP流。观察点:出图速度、有没有花屏、断不断。
我在现场的做法是,准备一台装了抓包工具的笔记本,用交换机的镜像口把NVR和IPC之间的流量镜像出来,过滤条件写http && ip.addr==192.168.1.64,然后点一次添加,整个六步的报文就全在眼前了。哪一步返回了500或者401,一眼就能看出来。
4.2 用抓包定位问题:一次完整的排障记录
说个具体案例。某项目现场,一台NVR添加IPC,现象是列表里能看到设备,点添加后转圈三十秒,最后提示"连接超时"。IPC侧日志显示收到了GetCapabilities请求,返回了200,之后就没有任何请求了。
抓包一看,NVR在GetCapabilities之后没有再发GetProfiles,而是等了三十秒超时。对比报文发现,我们的GetCapabilities响应里,Media能力节点的XAddr写的是 http://192.168.1.64:8080/onvif/media_service,而设备服务在80端口。NVR大概率是拿XAddr去做了一次可达性探测,8080端口没开,探测失败就放弃了。
这就是典型的"规范没说必须同端口,但对方默认同端口"。修复方式是把所有服务的XAddr统一到同一个端口下,用不同路径区分。改完之后添加秒过。
这件事给我的教训是:ONVIF的服务地址可以分散在不同端口,但在兼容场景下,收敛到同一个端口是最稳妥的选择。规范给了你自由度,不代表对方实现了这份自由度。
另一个常见案例是"能出图但很卡"。抓包发现NVR拉的是主码流,1080P 4Mbps,而NVR本身的解码能力只支持到2Mbps左右。解决办法是在GetProfiles里把子码流的token放在靠前的位置,引导NVR优先选子码流做预览。有些NVR会按返回顺序选第一个能解的流,顺序调一下就解决了。
4.3 云台和事件的联调要点
云台联调先测三件事:能不能读到PTZ配置、ContinuousMove能不能转、GotoPreset能不能回位。
GetConfigurations要返回一个合法的PTZConfiguration,里面NodeToken要指向GetNodes返回的节点,否则NVR的云台面板可能是灰的。ContinuousMove测试时把速度设成0.5,观察实际转动速度是不是中等,如果转得飞快或者不动,就是速度映射没做归一化。GotoPreset要注意预置位编号从1开始,有些NVR从0开始,越界会返回错误。
事件联调相对麻烦,因为要触发。我的办法是用IPC自己的移动侦测,在镜头前晃手,然后用抓包看NVR有没有收到PullMessages的响应,响应里有没有Motion事件。如果没有,先确认订阅创建成功,再确认事件topic拼写和NVR期待的完全一致。有些NVR对topic大小写敏感,差一个字母就匹配不上。
兼容层里我给事件模块做了个"事件别名"配置,可以把内部的topic映射成对方期待的名字,这个功能在不清楚对方实现细节时特别有用,改配置不用改固件。
5. 常见问题速查与排查心法
5.1 问题对照速查表
把对接中反复出现的问题整理成表,现场遇到直接对号入座:
| 现象 | 最可能的原因 | 快速验证方式 | 处理方向 |
|---|---|---|---|
| 添加列表里看不到设备 | 组播被过滤,或XAddrs地址不可达 | 抓包看有没有ProbeMatch | 检查IGMP配置,绑定发现网卡 |
| 能看到但添加超时 | 服务XAddr端口不通,或token名不匹配 | 抓包看卡在哪一步请求 | 统一服务端口,固定profile token |
| 提示用户名密码错误 | 时间偏差过大,或鉴权方式不支持 | 核对GetSystemDateAndTime返回值 | 放宽时间窗口,兼容多种鉴权 |
| 添加成功但黑屏 | 编码格式或分辨率超出NVR能力 | 抓包看GetProfiles返回参数 | 降级到H.264 1080P |
| 出图卡顿、马赛克 | 走了UDP且丢包,或拉了主码流 | 看NVR拉的是哪路流 | 切TCP传输,优先子码流 |
| 云台点不动 | 速度参数未归一化,或节点未声明 | 看GetNodes返回内容 | 做速度映射,补全节点 |
| 报警不联动 | topic名称不匹配,或订阅未建立 | 抓包看PullMessages响应 | 配置事件别名,实现简化推送 |
| 隔几分钟断一次 | RTSP并发超限,或会话保活缺失 | 看IPC连接数日志 | 提高并发上限,补KeepAlive |
这张表里,我个人觉得最值得记住的是第二行和第三行。对接失败的现象千变万化,但归因到最后,八成落在"地址对不对"和"时间对不对"这两件事上。
5.2 排查顺序:从下往上,不要从协议往上猜
现场排查我有个固定顺序,叫"三层法"。
第一层是物理和网络层。网线通不通、IP通不通、ping得通但端口通不通。用telnet 192.168.1.64 80和telnet 192.168.1.64 554两个命令,三十秒就能确认。很多"协议问题"到这一层就结束了。
第二层是协议交互层。抓包看请求和响应,重点看HTTP状态码和SOAP Fault。401是鉴权问题,400是报文格式问题,500是服务端内部错误,超时是网络或地址问题。ONVIF的SOAP Fault里通常会带一个子错误码,比如 ter:NotAuthorized、ter:ActionNotSupported,这个码比状态码有用得多,直接告诉你错在哪。
第三层才是业务逻辑层,也就是参数和行为的匹配问题。这一层最费时间,也最需要经验。
我见过很多人一上来就怀疑协议栈没实现,改代码改了两天,最后发现是网线插错了口。按顺序来,能省掉大量无用功。
提示:IPC侧一定要有完整的ONVIF请求日志,记录时间、来源IP、方法名、返回码、耗时。出问题时这份日志的价值远超抓包,因为它能告诉你"对方到底问了什么",而抓包只能告诉你"网线上跑了什么"。
5.3 兼容模式的选择策略与灰度思路
最后说说兼容模式怎么用。我的建议是"能不切就不切",默认走标准模式,只有在标准模式确实对不上时才切兼容模式。原因是兼容模式往往意味着某种妥协,比如放宽鉴权校验、固定token名、降级编码,这些妥协在提升兼容性的同时会牺牲一部分功能或安全性。
灰度思路是按项目类型分。新设备、新项目,全部走标准模式,逼着对方按规范实现;存量设备改造、老旧NVR混用的项目,直接开兼容模式,别在没有价值的地方消耗时间。我们内部有个简单的判断标准:如果对方NVR的固件发布时间在三年以内,先试标准模式;超过三年,直接上兼容模式。
另外建议把每次对接成功的NVR型号和对应的模式配置记下来,形成一个内部清单。这个清单积累到几十条之后,新项目的对接效率会有质的变化,很多时候看一眼型号就知道该用哪套参数。这件事听起来笨,但比任何自动化识别都可靠。
6. 关于这套方案,我个人踩坑后的几点体会
做了这么多轮对接,我最大的感受是:ONVIF全网通这件事,技术难度不在协议本身,而在"预期管理"。规范是一份契约,但契约的每一方对条款的理解都不一样,你要做的是让自己的实现能够覆盖足够多的理解方式,而不是去争论谁对谁错。
第二个体会是,日志比文档重要。文档告诉你规范怎么写,日志告诉你对方实际怎么问。我现在的习惯是,每接一款新NVR,第一件事不是看它的说明书,而是抓一次完整的添加流程,把报文存下来归档。这些报文积累起来,就是最真实的兼容性知识库。
第三个体会是关于测试成本。兼容层做出来之后,测试用例会爆炸式增长,五款NVR乘五种模式就是二十五种组合。我的做法是先做两两组合的正交表,覆盖主要路径,再针对历史上出过问题的组合做重点回归。全量测试在时间上根本不现实,学会抓主要矛盾比追求覆盖率更有意义。
最后分享一个特别好用的小技巧:在IPC的Web界面上做一个"ONVIF诊断"页面,一键生成当前配置摘要、最近二十条ONVIF请求日志、以及一份可以直接复制发给对方的文本报告。现场实施遇到问题时,把这份报告发回来,比在电话里描述十分钟现象有效得多。这个功能做起来不难,但对缩短问题定位时间的作用,比我做过的任何一项协议优化都大。