📹 第六章 SOAP及gSOAP实战
📄 一句话概括

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 秒实验

  1. 把字段从 5 个加到 20 个,看 SOAP 的包装开销涨多少(涨得比数据快,因为每个字段两个标签)。
  2. 按「100 路设备每 2 秒轮询一次」估算,SOAP 和 REST 一天的流量差多少。
  3. 给 REST 请求也加上一个 Authorization 头,看差距缩到多少。

常见误区

  1. 以为 Web Service 就等于 SOAP。 Web Service 是个更大的概念, REST 风格的接口也算 Web Service(严格说是「Web API」)。
  2. 以为 SOAP 被淘汰了。 在新项目里确实少用, 但监控、电信、银行的存量系统全是 SOAP,动不了。
  3. 以为 SOAP 体积大所以一定慢。 局域网上几百字节省略不计, 真正影响的是高频轮询时的带宽累积。
自测三问(点开对答案) 1. Web Service 的老三件套是什么?哪个死了? —— WSDL、SOAP、UDDI。**UDDI 死了**——因为实际场景里「服务目录」这一环根本不需要。 2. SOAP 响应 435 字节,其中多少是包装? —— **321 字节**,真数据只有 114 字节。**包装是数据的近三倍。** 3. ONVIF 选 SOAP 最不可替代的理由是哪条? —— **ONVIF 这个标准组织攥着 Profile 规范。**WSDL 和 schema 的优势现在都能被替代, **行业共识不能。**

下一节进工具链:soapcpp2 到底从 WSDL 生成了什么,四种产物各干什么用。

相关笔记