Web Service 的老三件套是 WSDL + SOAP + UDDI,其中 UDDI 已经死了。 同一件事 SOAP 花 191 字节、REST 花 20 字节——但 ONVIF 还是选了 SOAP,原因不在体积。
前面五节把 RPC、HTTP、XML、WSDL、SOAP 一块块拆开了,这一节把它们拼成一个概念。 这一节也是本章和第七章的转折点:讲完「是什么」,下一节开始讲「怎么用工具生成代码」。
一、三件套,死了一个
| 件 | 作用 | 现状 |
|---|---|---|
| WSDL | 接口说明书(06.01.04) | 活着,ONVIF 全靠它 |
| SOAP | 调用格式(06.01.05) | 活着,但新项目少用 |
| UDDI | 服务的「电话簿」,按名字查地址 | 2005 年后基本没人用 |
UDDI 为什么死:它想解决「我怎么知道世界上有哪些服务」。 但实际场景里,你永远知道设备在哪(就在局域网里、地址写在配置里),根本不需要全局目录。 这个教训很典型:一项技术的存亡取决于有没有人真的需要那一环,而不是它设计得多完整。 现在这一环被「配置中心」和「服务发现」接管了。
二、SOAP 和 REST,字节级别的差距
同一个请求:查设备信息。
| 风格 | 请求 | 字节 |
|---|---|---|
| SOAP | POST + 完整信封 + SOAPAction |
191 |
| REST | GET /api/device/info |
20 |
| 风格 | 响应字节 | 其中「包装」占多少 |
|---|---|---|
| SOAP | 435 | 321 |
| REST | 114 | 0 |
SOAP 的响应是 REST 的 3.8 倍,其中 321 字节全是信封、命名空间和重复的标签名。 真正的数据只有 114 字节——和 REST 一模一样。 在局域网里这点差别无所谓(差几百字节)。 但设备一多、轮询一频繁就变成带宽了: 100 路设备每 2 秒轮询一次,光包装就是每秒 16 KB,一天 1.4 GB。
三、那 ONVIF 为什么还用 SOAP
三条理由,都成立,而且都和「2008 年」有关。
| 理由 | 说明 | 现在还算不算数 |
|---|---|---|
| 有 WSDL | 接口自描述,客户端能自动生成代码 | 算,OpenAPI 补上了这条 |
| 有 schema | 类型定义严格,跨厂商不会各说各话 | 算,但 JSON Schema 也行 |
| 有标准组织 | ONVIF 攥着 Profile 规范 | 算,这是唯一不可替代的 |
第一行是当年最硬的:2008 年没有 OpenAPI,REST 只是「一种风格」,不是「一份规范」, 各写各的,客户端没法自动生成代码。 现在反过来了:OpenAPI 把这条补上,所以新设备越来越多给 REST。 但存量设备全是 SOAP——这就是做监控客户端必须学 SOAP 的唯一理由。 第三行是 ONVIF 真正的护城河:Profile S/G/T 这套规范是行业共识, 不是技术选型能替代的(07.01.04 讲 Profile)。
四、什么时候该选哪个
| 场景 | 建议 | 理由 |
|---|---|---|
| 对接存量 ONVIF 设备 | SOAP | 没得选 |
| 自己设计新设备接口 | REST + OpenAPI | 体积小、工具链好 |
| 需要严格类型和校验 | 两者都行 | SOAP 靠 XSD,REST 靠 JSON Schema |
| 高频轮询、低带宽 | REST,甚至 gRPC | 包装开销直接影响带宽 |
第一行和第二行不矛盾:很多设备现在是「ONVIF 端口 + 私有 REST 端口」双开, 老客户端走 ONVIF,自家 App 走 REST。 这是过渡期的常态,也是为什么你会在一台摄像头上看到两套接口。
五、动手 Demo:同一件事,SOAP 和 REST 各花多少字节
Demo 把同一个「查设备信息」用两种风格各写一遍,量字节。 关键是拆出「包装」占了多少——那部分是真数据以外的开销。
soap_req = ('POST /onvif/device_service HTTP/1.1\r\n'
'Content-Type: application/soap+xml\r\n'
'SOAPAction: http://www.onvif.org/ver10/device/wsdl/GetDeviceInformation\r\n'
'\r\n'
'<?xml version="1.0"?><s:Envelope xmlns:s="..."><s:Body>'
'<tds:GetDeviceInformation/></s:Body></s:Envelope>')
rest_req = "GET /api/device/info HTTP/1.1\r\n\r\n"
print(len(soap_req.encode()), len(rest_req.encode())) # 191 20
# 响应里「包装」的算法:总字节 - 纯数据字节
print(len(soap_resp), len(soap_resp) - len("".join(values))) # 435 321
实跑输出:
--------------------------------------------------------------------
同一件事,SOAP 和 REST 各花多少字节
--------------------------------------------------------------------
**ONVIF 用 SOAP,很多新设备也提供 REST 接口。这一节量一下两种风格的代价。**
**同一个请求:查设备信息。**
风格 请求 字节
------------------------------------------------------------------
SOAP POST + 完整信封 + SOAPAction 191
REST GET /api/device/info 20
风格 响应字节 其中「包装」占多少
------------------------------------------------
SOAP 435 321
REST 114 0
**SOAP 的响应是 REST 的 3.8 倍**,多出来的全是信封、命名空间和重复的标签名。
**在局域网里这点差别无所谓**(差几百字节),**但设备一多、轮询一频繁,就变成带宽了。**
**那为什么 ONVIF 还用 SOAP**:
原因 说明
------------------------------------------------------------
有 WSDL 接口自描述,客户端能自动生成
有 schema 类型定义严格,跨厂商不会各说各话
有标准组织 ONVIF 攥着 Profile 规范
**这三条在 2008 年是决定性优势**:那时候没有 OpenAPI,**REST 是「风格」,不是「规范」**,
各写各的。
**现在反过来了**:OpenAPI 补上了这条,所以新设备越来越多给 REST。
**但存量设备全是 SOAP**,所以做监控客户端,SOAP 必须会。
请求体积差 9.5 倍,响应差 3.8 倍——请求差得更多,
因为请求里那一长串 SOAPAction 占了 76 个字节。
「包装占 321 字节」这个数是这么算的:总字节减去「纯数据」(五个字段值直接拼起来)。
这个口径要说清楚,否则 321 这个数没意义。
注意这里比的是「同一份数据的两种表达」,不是「同一台设备的两种真实接口」。
真设备上 REST 还可能带认证头、分页参数,字节会更接近。
30 秒实验
- 把字段从 5 个加到 20 个,看 SOAP 的包装开销涨多少(涨得比数据快,因为每个字段两个标签)。
- 按「100 路设备每 2 秒轮询一次」估算,SOAP 和 REST 一天的流量差多少。
- 给 REST 请求也加上一个
Authorization头,看差距缩到多少。
常见误区
- 以为 Web Service 就等于 SOAP。 Web Service 是个更大的概念, REST 风格的接口也算 Web Service(严格说是「Web API」)。
- 以为 SOAP 被淘汰了。 在新项目里确实少用, 但监控、电信、银行的存量系统全是 SOAP,动不了。
- 以为 SOAP 体积大所以一定慢。 局域网上几百字节省略不计, 真正影响的是高频轮询时的带宽累积。
自测三问(点开对答案)
1. Web Service 的老三件套是什么?哪个死了? —— WSDL、SOAP、UDDI。**UDDI 死了**——因为实际场景里「服务目录」这一环根本不需要。 2. SOAP 响应 435 字节,其中多少是包装? —— **321 字节**,真数据只有 114 字节。**包装是数据的近三倍。** 3. ONVIF 选 SOAP 最不可替代的理由是哪条? —— **ONVIF 这个标准组织攥着 Profile 规范。**WSDL 和 schema 的优势现在都能被替代, **行业共识不能。**下一节进工具链:soapcpp2 到底从 WSDL 生成了什么,四种产物各干什么用。
- ☐ (本节完,下一节 06.02.01 soapcpp2的用法)