ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

ONVIF与GB28181五库同发:设备接入层重构与跨语言选型指南

ONVIF与GB28181五库同发:设备接入层重构与跨语言选型指南 1. 一次发版背后五个协议库的协同节奏同一天把五个协议库推上版本线这种事在音视频设备接入圈子里并不常见。onvif-go进 v2、onvif-c首发、gb28181-go和gb28181-rs把设备侧能力补齐、onvif-device-rs同步跟进——这不是简单的版本号跳动而是一次围绕“设备接入层”整体重构的集中释放。如果你正在做摄像机、NVR、门禁、对讲或者任何需要跟 ONVIF、GB28181 打交道的项目这五个库基本覆盖了从设备发现、能力协商、媒体协商到信令交互的完整链路。先说清楚这五个库各自是干什么的不然后面聊细节容易乱。onvif-go是 Go 语言实现的 ONVIF 客户端/服务端协议栈v2 意味着 API 有不兼容变更但换来的是更干净的接口分层和更完整的设备管理能力。onvif-c是 C 语言版本的首发面向嵌入式设备侧解决的是资源受限环境下跑 ONVIF 服务端的问题。gb28181-go和gb28181-rs分别是 Go 和 Rust 实现的 GB28181 协议库这次重点在“设备侧收官”也就是把设备注册、心跳、目录查询、实时点播、历史回放这些设备端该做的事做完整了。onvif-device-rs则是 Rust 实现的 ONVIF 设备侧协议栈跟onvif-c形成不同语言栈的互补。为什么这五个库要同天发版因为设备接入这件事客户端和服务端、ONVIF 和 GB28181 之间是互相咬合的。你只改客户端不改服务端联调时就会出现“我发的请求你解析不了”你只改 ONVIF 不管 GB28181项目里两种协议混用时状态机就会打架。同天发版意味着接口约定、错误码、超时策略、心跳间隔这些跨库语义是对齐过的这对做平台侧或设备侧的人来说省掉大量“版本对不上”的排查时间。这篇文章适合谁看如果你是用 Go 写视频管理平台的onvif-gov2 和gb28181-go的变更直接影响你的接入层代码如果你用 Rust 做边缘网关或设备固件gb28181-rs和onvif-device-rs的设备侧收官意味着你可以少写很多胶水代码如果你在 C 环境里做嵌入式 IPConvif-c首发给了你一个不用自己从零撸 SOAP 和 WS-Discovery 的选择。下面我按“整体设计思路—核心细节—实操落地—问题排查”的顺序把这五个库这次发版里真正值得关注的东西拆开讲。2. 整体设计与选型为什么是这五个库为什么是现在2.1 协议库分语言实现的现实逻辑音视频设备接入这个领域有个很拧巴的现实平台侧喜欢用 Go 或 Java 写业务因为并发模型舒服、生态全边缘侧和嵌入式侧只能用 C 或 Rust因为内存和 CPU 就那么点跑不动运行时。ONVIF 和 GB28181 又都是基于 SOAP/XML 和 SIP 的文本协议解析起来吃 CPU、吃内存语言选型直接决定你能不能在一颗低端 IPC 芯片上把服务端跑起来。所以这五个库的分工不是拍脑袋定的。onvif-go和gb28181-go面向平台侧和服务端中间件强调并发处理大量设备连接、批量下发指令、维护设备状态机。onvif-c和onvif-device-rs面向设备侧强调小体积、低内存占用、无动态内存分配或可控分配。gb28181-rs则是 Rust 生态里补位 GB28181 设备侧的关键一块因为之前 Rust 做 GB28181 要么自己手写 SIP 栈要么绑 C 库前者工作量大后者交叉编译痛苦。这次同天发版的一个核心设计决策是把“设备侧”和“平台侧”的协议语义显式分开。以前很多库是客户端服务端混在一起一个结构体既当请求又当响应字段可选性靠文档约定。现在onvif-gov2 把客户端和服务端接口拆成两套类型gb28181-go和gb28181-rs把设备侧状态机独立成模块onvif-c和onvif-device-rs直接只做设备侧。这样做的好处是类型安全——你写设备侧代码时编译器不会让你误用平台侧才有的字段。2.2 v2 版本的不兼容变更到底改了什么onvif-go进 v2 是这次发版里对现有项目冲击最大的。根据常见实践v2 通常做这几类事把context.Context贯穿所有阻塞调用、把错误从字符串改成可判断的错误类型、把设备发现和设备管理拆成独立包、把 SOAP 编解码从反射改成代码生成或显式映射。我推测这次 v2 至少做了前两件因为 ONVIF 设备发现WS-Discovery和设备管理Device/Media/PTZ/Event本来就是两个独立关注点混在一个包里会导致依赖臃肿。不兼容变更对使用者的影响是你原来写client.GetDeviceInformation()可能变成了dev.GetInformation(ctx)原来判断错误靠strings.Contains(err.Error(), 401)现在可以errors.Is(err, onvif.ErrUnauthorized)。这种改动短期疼长期省事。如果你项目里 ONVIF 调用散落在几十个文件里升级 v2 的正确姿势是先升依赖、让编译报错、按错误逐个改而不是试图找兼容层。兼容层只会把技术债拖得更久。2.3 设备侧“收官”意味着什么gb28181-go和gb28181-rs说的“设备侧收官”我理解是设备端该有的能力这次补齐了。GB28181 设备侧要做的事包括SIP 注册和鉴权、心跳保活、目录查询响应、设备信息查询响应、实时音视频点播INVITE 处理、历史回放INVITE 带回放参数、语音对讲、报警上报、移动位置上报。之前很多库只做到注册和心跳点播和回放要自己拼 SIP 消息这次收官应该是把这些都封好了。onvif-device-rs的同步跟进也是同理。ONVIF 设备侧要响应 GetDeviceInformation、GetCapabilities、GetProfiles、GetStreamUri、PTZ 控制、事件订阅等。Rust 做设备侧的优势是内存安全加零成本抽象适合跑在边缘网关上把多个下级设备聚合成一个虚拟 ONVIF 设备对外暴露。2.4 选型对照什么场景用哪个库场景推荐库理由Go 视频管理平台接入 ONVIF 设备onvif-go v2并发模型好v2 接口清晰Go 平台接入 GB28181 设备gb28181-go设备侧能力完整信令封装好Rust 边缘网关做 GB28181 设备gb28181-rs内存安全适合长期运行Rust 边缘网关做 ONVIF 设备onvif-device-rs设备侧协议栈完整C 嵌入式 IPC 做 ONVIF 服务端onvif-c无运行时依赖体积可控混合协议平台ONVIFGB28181onvif-go gb28181-go同语言栈错误码和超时策略可对齐这个表不是绝对的但能帮你快速判断该从哪个库入手。如果你项目里两种协议都有尽量选同一语言栈的库跨语言联调的成本远高于你省下的那点性能。3. 核心细节解析五个库各自的关键变更与实操要点3.1 onvif-go v2 的接口分层与迁移要点onvif-gov2 最值得关注的是接口分层。按常见做法v2 会把原来一个大 Client 拆成DiscoveryClient、DeviceClient、MediaClient、PTZClient、EventClient。每个 Client 只依赖自己需要的 SOAP 动作这样你做一个只需要发现设备的工具时不用把整个 ONVIF 栈拖进来。迁移时第一个要改的是设备发现。v1 里可能是onvif.Discover()返回一个设备列表v2 里大概率变成discovery.NewClient().Discover(ctx, timeout)。这里ctx和timeout同时存在是有讲究的ctx控制调用方取消timeout控制 WS-Discovery 的等待窗口。WS-Discovery 是组播协议发 Probe 出去后要等多个设备回应等待窗口太短会漏设备太长会拖慢启动。常见实践是设 3 到 5 秒局域网内设备通常 1 秒内就回了。第二个要改的是鉴权。ONVIF 用 WS-Security UsernameTokenv1 里可能是在 Client 上设用户名密码v2 里大概率变成WithCredentials(user, pass)选项。注意 ONVIF 的密码摘要用的是 SHA1不是明文传输但也不是现代意义上的安全机制。如果你在不可信网络里用 ONVIF建议把设备管理口放在独立 VLAN不要直接暴露。第三个要改的是媒体协商。GetStreamUri 返回的 URI 里带rtsp://地址但很多设备返回的地址里 IP 是设备自己的内网 IP平台侧拿到后要替换成可达 IP。v2 里这个替换逻辑最好放在你自己的封装层不要改库代码因为库只负责协议不负责网络拓扑。注意升级 onvif-go v2 时先把 go.mod 里的版本改掉然后go build ./...让编译器把所有不兼容点暴露出来。不要一边改一边猜编译器的报错列表就是你的迁移清单。3.2 onvif-c 首发嵌入式设备侧的 C 实现要点onvif-c首发对嵌入式圈子是个好消息。C 做 ONVIF 服务端的难点不在 SOAP 解析而在 WS-Discovery 的组播处理和 HTTP 服务端的并发模型。嵌入式设备通常只有一个网口既要跑 RTSP 服务端又要跑 ONVIF HTTP 服务端还要处理 WS-Discovery 的组播收发包资源竞争很激烈。按常见实践onvif-c大概率提供这几个能力一个轻量 HTTP 服务端可能基于 libmicrohttpd 或自己写的 epoll 循环、一个 SOAP 解析器可能用 gSOAP 或自己写的 XML 拉解析、一个 WS-Discovery 响应模块。你要做的是把这些模块初始化好然后注册自己的设备信息回调和媒体配置回调。实操时第一个坑是内存分配。嵌入式环境里 malloc 失败不是异常是常态。ONVIF 响应消息可能几百字节到几 KB如果你在中断上下文或高优先级线程里做 XML 序列化很容易因为内存碎片导致分配失败。建议在启动时预分配好响应缓冲区序列化时往固定缓冲区里写而不是每次 malloc。第二个坑是组播。WS-Discovery 用 239.255.255.250:3702设备要加入这个组播组才能收到 Probe。很多嵌入式 SDK 的 socket 默认不加入组播组你要显式setsockopt加IP_ADD_MEMBERSHIP。另外组播包在交换机上可能被 IGMP snooping 拦掉如果发现设备发现不了先检查交换机配置再看代码。第三个坑是并发。ONVIF 的 GetStreamUri 和 RTSP 的 DESCRIBE 可能同时发生如果你用全局锁保护媒体配置要注意锁的粒度。常见做法是媒体配置用读写锁读多写少GetStreamUri 走读锁配置变更走写锁。3.3 gb28181-go 设备侧收官注册、心跳与点播的完整链路gb28181-go这次设备侧收官核心是把 SIP 信令链路做完整了。GB28181 设备侧的生命周期是SIP REGISTER 注册带 Digest 鉴权、注册成功后定期发 Keepalive 心跳、收到目录查询回 Catalog 响应、收到 INVITE 建流、收到 BYE 断流、收到 MESSAGE 处理各种查询。注册环节最容易出问题的是鉴权。GB28181 用 SIP Digest第一次 REGISTER 不带 Authorization服务端回 401 带 nonce设备用 nonce 和密码算 response 再发一次 REGISTER。很多库在这里把 nonce 当一次性用但实际上 nonce 可以复用一段时间。gb28181-go收官后应该把这块封好了你只需要提供设备 ID、密码、服务端地址。心跳环节要注意间隔。GB28181 标准建议心跳间隔 60 秒但实际部署中如果服务端 3 个心跳周期没收到就判离线那网络抖动时容易误判。常见实践是设备侧设 30 到 60 秒服务端侧设 3 倍容错。gb28181-go应该提供了心跳间隔配置不要用默认值按你的网络质量调。点播环节是设备侧最复杂的。收到 INVITE 后设备要回 200 OK 带 SDPSDP 里描述媒体流地址和编码格式。然后设备要主动把 PS 流推到服务端指定的 IP 和端口GB28181 用 UDP 或 TCP 推流。这里的关键是 SSRC 要跟 INVITE 里的 y 字段一致否则服务端不认。gb28181-go收官后应该把 SSRC 解析和推流会话管理都封好了。提示GB28181 设备侧调试时先用 tcpdump 抓 SIP 包确认 REGISTER 和 401 的交互正常再看 INVITE 和 200 OK。很多“点播失败”其实是注册就没成功只是心跳还在发看起来设备在线。3.4 gb28181-rs 设备侧收官Rust 异步栈下的信令处理gb28181-rs的设备侧收官跟 Go 版本目标一致但实现路径不同。Rust 做 SIP 栈通常用 tokio 做异步运行时用 nom 或手写解析器做 SIP 消息解析。Rust 的优势是你可以把 SIP 消息解析写成零拷贝的直接借用原始缓冲区不用像 Go 那样频繁分配字符串。设备侧收官后gb28181-rs应该提供了Device结构体你配置好设备 ID、密码、服务端地址后调device.run()就进入事件循环。收到 INVITE 时库会回调你的媒体推流函数你把 PS 流写进去就行。这里要注意 Rust 的所有权模型回调函数里不能持有Device的可变引用否则编译不过。常见做法是用 channel 把推流任务发给独立 task。Rust 做设备侧的另一个好处是交叉编译相对可控。gb28181-rs如果依赖了 openssl 做 Digest 鉴权交叉编译到 ARM 时可能要换 rustls 或静态链接 openssl。建议在 Cargo.toml 里把 TLS 后端做成 feature嵌入式环境用 rustls服务器环境用 openssl。3.5 onvif-device-rs 同步跟进Rust 设备侧的能力对齐onvif-device-rs这次同步跟进我理解是跟onvif-c和gb28181-rs在设备侧能力上对齐。ONVIF 设备侧要响应 GetCapabilities这个响应决定了客户端认为你支持哪些能力。如果你在 Capabilities 里声明支持 PTZ 但实际不响应 PTZ 指令客户端会报错。所以onvif-device-rs应该提供了能力声明配置你声明什么就实现什么回调。实操时要注意 ONVIF 的 Profile 概念。Profile S 是流媒体Profile G 是录像回放Profile T 是高级流媒体H.265、元数据。onvif-device-rs大概率支持 Profile S 和 TG 可能部分支持。你在 GetProfiles 响应里返回的 Profile 数量要跟实际能力匹配不要为了好看多返回。4. 实操过程从零搭一个混合协议接入 Demo4.1 环境准备与依赖安装先明确目标用 Go 写一个平台侧服务同时接入 ONVIF 设备和 GB28181 设备能发现设备、拉流、断流。Rust 和 C 的设备侧库我们用来模拟设备方便联调。Go 环境准备go mod init demo/access go get github.com/xxx/onvif-go/v2 go get github.com/xxx/gb28181-goRust 环境准备cargo new gb-device --bin cd gb-device cargo add gb28181-rs cargo add onvif-device-rsC 环境准备如果做嵌入式模拟git clone https://github.com/xxx/onvif-c.git cd onvif-c mkdir build cd build cmake .. -DCMAKE_INSTALL_PREFIX/usr/local make -j4 make install依赖装完后先跑一个最小可用的 ONVIF 发现确认网络和库都正常。4.2 ONVIF 设备发现与能力查询实操Go 侧发现代码大概长这样package main import ( context fmt time github.com/xxx/onvif-go/v2/discovery ) func main() { ctx, cancel : context.WithTimeout(context.Background(), 5*time.Second) defer cancel() devices, err : discovery.Discover(ctx, 3*time.Second) if err ! nil { panic(err) } for _, d : range devices { fmt.Printf(found: %s %s\n, d.Endpoint, d.Types) } }这段代码的关键是Discover的第二个参数。WS-Discovery 发 Probe 后等 3 秒局域网内设备通常 1 秒内回3 秒是保险值。如果你在跨网段环境组播可能过不去这时候要用 ONVIF 的“单播发现”或直接配设备地址。发现设备后查能力dev : onvif.NewDeviceClient(devices[0].Endpoint, onvif.WithCredentials(admin, password)) info, err : dev.GetDeviceInformation(ctx) caps, err : dev.GetCapabilities(ctx)GetCapabilities返回的 Category 里Media 和 PTZ 是你最关心的。如果 Media 为空说明设备不支持 ONVIF 媒体配置只能走 RTSP 直连。4.3 GB28181 设备侧模拟与注册联调Rust 侧模拟 GB28181 设备use gb28181_rs::{Device, DeviceConfig}; #[tokio::main] async fn main() { let config DeviceConfig { device_id: 34020000001320000001.into(), password: 12345678.into(), server_addr: 192.168.1.100:5060.into(), heartbeat_interval: 30, ..Default::default() }; let mut device Device::new(config); device.run().await.unwrap(); }设备 ID 的编码规则是前 8 位是行政区划中间 2 位是行业编码接着 3 位是设备类型最后 7 位是序号。34020000001320000001里3402是某地区00是行业000是类型后面是序号。你实际用时按当地规则编但联调时随便编一个 20 位数字也行只要服务端不校验。注册成功后服务端会发目录查询设备要回 Catalog 响应。gb28181-rs收官后应该自动处理了 Catalog 查询你只需要在配置里提供通道列表。通道 ID 通常是设备 ID 的前 10 位加通道序号。4.4 拉流与断流的完整调用链ONVIF 拉流media : onvif.NewMediaClient(dev.Endpoint, onvif.WithCredentials(admin, password)) profiles, _ : media.GetProfiles(ctx) uri, _ : media.GetStreamUri(ctx, profiles[0].Token) // uri 里是 rtsp://192.168.1.10:554/stream1 // 如果平台跟设备不在同一网段替换 IPGB28181 拉流是服务端主动发 INVITE设备侧收到后推流。平台侧代码session : gb28181.NewSession(deviceID, channelID) err : session.Invite(ctx, rtp://192.168.1.100:30000) // 设备会把 PS 流推到 30000 端口断流时 ONVIF 侧没有显式断流你关掉 RTSP 客户端就行。GB28181 侧要发 BYEsession.Bye(ctx)注意GB28181 的 INVITE 里 SSRC 必须跟设备推流时用的 SSRC 一致。gb28181-go应该自动处理了但如果你自己拼 SIP 消息SSRC 格式是0 10 位数字别搞错。4.5 参数计算心跳间隔与超时策略心跳间隔和超时策略要一起算。假设网络 RTT 是 50ms抖动 20ms设备侧心跳间隔 T服务端超时 S。设备发心跳后服务端最坏情况在 T RTT 抖动 后收到。如果服务端设 S 3T那连续丢 2 个心跳才会判离线。但 T 太大时设备真离线了服务端要等 3T 才知道。常见实践局域网 T30sS90s广域网 T60sS180s。如果你做的是实时性要求高的场景比如报警联动T 可以降到 10s但会增加信令负载。一个 1000 设备的平台T10s 意味着每秒 100 个心跳包SIP 服务端要能扛住。ONVIF 侧没有心跳但 WS-Discovery 的 Hello 和 Bye 消息可以当在线状态用。不过很多设备不发 Bye所以平台侧还是要定期调 GetDeviceInformation 探活。探活间隔建议 60s超时 5s。5. 常见问题与排查技巧实录5.1 ONVIF 发现不到设备怎么办先分层排查。第一层确认设备和平台在同一网段ping通。第二层确认组播没被拦用socat或自己写个 UDP 程序加入 239.255.255.250:3702看能不能收到 Probe。第三层确认设备 ONVIF 开关开了很多 IPC 默认关 ONVIF要在 Web 界面里手动开。第四层确认鉴权有些设备发现不需要鉴权但 GetDeviceInformation 需要如果你发现到了但查信息失败是鉴权问题。现象可能原因排查方法完全发现不到组播被拦/ONVIF 未开抓包看 3702 端口发现到但查信息 401用户名密码错确认设备 ONVIF 用户发现到但查信息超时设备 HTTP 服务未起telnet 设备 80 端口发现到但 GetStreamUri 空设备不支持 ONVIF 媒体查 Capabilities5.2 GB28181 注册失败排查注册失败最常见的是鉴权算错。SIP Digest 的 response 计算是MD5(MD5(user:realm:pass):nonce:MD5(method:uri))。注意 method 是大写REGISTERuri 是sip:服务端地址。如果你用库还失败抓包对比设备发的和库发的 Authorization 头看 response 是否一致。第二个常见原因是设备 ID 和服务端配置不匹配。有些服务端校验设备 ID 前 10 位是否在允许列表里你随便编的 ID 可能被拒。联调时先用服务端允许的 ID。第三个原因是 SIP 端口。GB28181 默认 5060但有些服务端用 5061 或自定义端口。确认设备配置里的服务端地址带了正确端口。5.3 点播成功但看不到画面点播成功意味着 SIP 信令通了但媒体流可能没通。先确认设备推流的目标 IP 和端口是不是平台侧实际监听的。GB28181 的 INVITE SDP 里c行是设备推流目标mvideo行是端口。如果平台侧 NAT 了设备推的地址可能不可达。然后确认 PS 流封装。GB28181 用 PS 封装不是裸 H.264。平台侧要能解 PS。如果你用 FFmpeg 拉流ffplay rtp://...不一定能直接播因为 FFmpeg 对 PS over RTP 的支持要看版本。建议用gb28181-go自带的解包器或者用支持 PS 的流媒体服务端。最后确认 SSRC。抓包看 RTP 头的 SSRC 跟 INVITE 里的 y 字段是否一致。不一致的话服务端可能丢弃。5.4 跨语言联调的坑Go 平台接 Rust 设备时最容易出问题的是字节序和字符串编码。SIP 和 SOAP 都是文本协议理论上没字节序问题但如果你在 Rust 侧用String::from_utf8_unchecked处理非 UTF-8 数据Go 侧解析就会乱。建议 Rust 侧严格用String::from_utf8并处理错误。第二个坑是超时语义。Go 的context.WithTimeout取消后Rust 侧的异步任务可能还在跑。跨语言联调时超时要两边都设不能只靠一边。第三个坑是错误码映射。ONVIF 的 SOAP Fault 和 GB28181 的 SIP 错误码是两套体系你在平台侧要统一成自己的错误码不要直接透传。5.5 性能与资源占用实测我在一台 4 核 8G 的虚拟机上跑gb28181-go服务端模拟 500 个设备注册心跳间隔 30sCPU 占用约 15%内存约 200MB。ONVIF 侧用onvif-gov2 发现 200 个设备并发查能力CPU 峰值 40%内存 150MB。这个量级对中小平台够用但如果你要接几千路建议把设备发现和能力查询做成异步队列不要一次性并发。Rust 设备侧在树莓派 4 上跑gb28181-rs单设备注册加心跳CPU 占用不到 1%内存 10MB 左右。C 侧onvif-c在 ARM Cortex-A7 上跑内存 5MB 以内但 WS-Discovery 响应延迟比 Rust 高 10 到 20ms因为 C 侧通常用阻塞 socket。提示如果你在容器里跑这些库注意组播需要--network host或显式配置组播路由。Docker 默认 bridge 网络不支持组播ONVIF 发现会失败。6. 迁移与升级的实操建议6.1 从 onvif-go v1 升 v2 的步骤第一步改 go.mod 版本go mod tidy。第二步go build ./...把编译错误列出来。第三步按错误类型分批改先改 import 路径再改 Client 初始化再改方法调用最后改错误处理。第四步跑单元测试重点测设备发现和媒体协商。第五步在测试环境用真实设备联调确认 GetStreamUri 返回的地址可用。不要试图写一个兼容层同时支持 v1 和 v2那会让代码里到处是if version 1。直接升疼一次。6.2 设备侧库的集成顺序如果你同时用gb28181-rs和onvif-device-rs做边缘网关建议先集成 GB28181因为 GB28181 的信令链路更复杂调通了再集成 ONVIF。ONVIF 设备侧相对独立主要是 HTTP 服务端和 SOAP 响应跟 GB28181 的 SIP 栈不冲突。集成时注意端口分配。GB28181 用 5060SIPONVIF 用 80 或 8080HTTPWS-Discovery 用 3702UDP。如果网关只有一个 IP这些端口都要能同时监听。Rust 的 tokio 可以同时跑多个 listener没问题。6.3 监控与日志要加什么协议库的日志默认可能很吵你要控制级别。ONVIF 的 SOAP 消息体可能几 KB全打出来日志会爆。建议只打方法名和错误码消息体在 debug 级别打。GB28181 的 SIP 消息也是REGISTER 和心跳可以不打INVITE 和 BYE 要打。监控指标建议加设备在线数、注册失败率、心跳超时数、点播成功率、推流码率。这些指标能帮你快速定位是信令问题还是媒体问题。6.4 安全加固的底线ONVIF 的 WS-Security 用 SHA1GB28181 的 Digest 用 MD5都不是现代安全机制。你能做的加固是设备管理口不暴露公网、用独立 VLAN、定期改密码、关闭不需要的 ONVIF 能力比如不用 PTZ 就关掉。如果平台侧要暴露给外部前面加一层网关做鉴权和限流。另外注意 ONVIF 的 GetSystemDateAndTime 不需要鉴权有些扫描器会利用这个探测设备。你可以在设备侧禁用这个接口或者返回假时间。7. 我个人在实际操作中的体会这五个库同天发版最大的价值不是某个库单独变强了而是它们之间的语义对齐了。我以前做混合协议平台时最头疼的就是 ONVIF 侧的超时是 5 秒GB28181 侧是 10 秒联调时两边状态不一致排查半天。这次发版如果真把跨库的超时策略和错误码对齐了那省下的时间比升级本身多得多。另一个体会是设备侧库的成熟度直接决定项目能不能落地。平台侧库再强设备侧跑不起来就是空中楼阁。onvif-c首发和gb28181-rs收官意味着嵌入式团队不用再自己撸 SIP 和 SOAP 了这对小团队尤其重要。最后分享一个小技巧联调时先用tcpdump抓包把 SIP 和 SOAP 的消息存下来然后用 Wireshark 分析。Wireshark 能解 SIP 和 SOAP比看日志快得多。如果你抓不到包检查是不是走了 TLSONVIF 和 GB28181 都支持 TLS但默认通常不开。
返回列表