Web of Things(WoT)配置文件

W3C 工作草案

关于本文档的更多详细信息
此版本:
https://www.w3.org/TR/2025/WD-wot-profile-20251104/
最新发布版本:
https://www.w3.org/TR/wot-profile/
最新编辑草案:
https://w3c.github.io/wot-profile/
历史:
https://www.w3.org/standards/history/wot-profile/
提交 历史
编辑:
Michael Lagally (Oracle Corp.)
Ben Francis (受邀专家)
Sebastian Kaebisch (Siemens AG)
Tomoaki Mizushima (Internet Research Institute, Inc.)
前任编辑:
Michael McCool (当时任职于 Intel Corp.)
Ryuichi Matsukura (当时任职于 Fujitsu Ltd.)
反馈:
GitHub w3c/wot-profile拉取 请求新建 issue未关闭 issue
public-wot-wg@w3.org,主题行填写 [wot-profile] … 消息主题 …存档
贡献者
在 GitHub 仓库中

摘要

本规范定义了一个 配置文件机制和一组 配置文件, 使开箱即用的 互操作性能够在 Web Things 及其 消费者之间,在 Web of Things 上实现。

开箱即用的互操作性意味着,任何符合给定 配置文件消费者 都可以与任何符合相同 配置文件Thing 进行交互,而无需额外 定制。

配置文件是一份技术规范,它提供了一组 断言,合规的 消费者Things 必须符合这些断言。

配置文件机制提供了一种方式,用于表明 给定 Thing 符合一个或多个 配置文件,即在其 Thing Descriptionprofile 成员中引用这些 配置文件的 标识符。

本规范定义了三个配置文件:

本规范中定义的 配置文件 共享一组通用约束,这些 配置文件的实现也必须符合这些约束。这 包括对单位、日期格式、安全 机制、发现机制、链接关系和 错误的约束。

本规范的未来版本或扩展 规范可以定义其他配置文件

本文档状态

本节描述本文档在 发布时的状态。当前 W3C 出版物和本技术报告 最新修订版的列表可在 W3C 标准和草案 索引中找到。

本文档由 Web of Things 工作 组作为工作草案发布,使用 推荐标准 轨道

作为工作草案发布并不意味着 W3C 及其 成员的认可。

本文档是一份草案文档,可能随时被 更新、替换或 废弃。除非作为进行中的工作, 否则不适合引用本文档。

本文档由一个在 W3C 专利政策下运作的小组制作。 W3C 维护一份与该小组 交付物相关的任何 专利披露公开列表; 该页面还包括披露专利的 说明。任何实际知晓 某项专利且认为该专利包含必要 权利要求的个人,必须按照 W3C 专利政策第 6 节披露该信息。

本文档受 2025 年 8 月 18 日 W3C 流程 文档约束。

1. 引言

1.1 动机

Web of Things (WoT) 旨在通过使用并扩展现有的、 标准化 Web 技术,来应对物联网 (IoT) 的碎片化。

W3C WoT Thing Description [wot-thing-description11] 规范定义了一种信息模型和基于 JSON 的 表示格式,用于描述互联设备的能力以及与其 通信所用的接口。Thing Descriptions 被 设计为与协议无关,并且足够灵活,能够 描述各种现有的(“棕地”)IoT 设备。

为了提供这种灵活性,Thing Description 规范包含了若干扩展 点,包括协议绑定、载荷绑定、 安全机制、链接关系和语义上下文。只要 设备的所有能力都可以使用 Thing Description 来描述,并且 消费者实现了所用的所有 扩展,则该消费者就应该能够与 该设备互操作。然而,这种可扩展架构的结果是, 任何给定的消费者只能与 可能的 Web Things 的一个子集互操作。

本规范旨在补充 Thing Description [wot-thing-description11] 规范,通过使用“配置文件”来实现临时互操作性。 配置文件规定了一组有限的 扩展和默认值,Thing 可以受这些扩展和默认值约束, 以保证与任何实现该 配置文件的消费者实现开箱即用的 互操作性

配置文件 专门面向新的(“绿地”)实现而设计,在这些实现中, 开发者可以自由地符合规定性的 协议绑定和一组通用约束,从而 受益于这种额外层级的互操作性。

本规范的未来版本或扩展 规范可以定义其他配置文件

1.2 用例和需求

Web of Things Interest Group 从代表各个 不同行业的利益相关方那里收集了 Web of Things 的用例。这包括垂直的、 特定领域的用例,以及适用于多个应用领域的 横向用例 [wot-usecases]。

若干特定领域 用例提到了对来自多个厂商的 设备进行轻松集成的需求。这对于需要 “多厂商系统集成”和“开箱即用互操作性”的 跨领域 用例尤其重要。

配置文件的一组 需求是从这些用例中推导出来的。

1.3 开箱即用的 互操作性

从较高层面看,开箱即用的互操作性意味着 消费者 被保证能够使用某个 Thing 的每一项能力,而无需针对该 Thing 进行 特定定制。

本规范中使用的开箱即用互操作性的完整定义 包含多个层级。下面的分类采用了“H2020 - CREATE-IoT Project - Recommendations for commonalities and interoperability profiles of IoT platforms” [H2020-CREATE-IoT] 报告中的术语。下面的定义经过调整,以反映 WoT 配置文件的范围。

1.3.1 技术 互操作性

技术互操作性通常 与通信协议以及这些协议运行所需的 基础设施相关。这意味着需要就一种共同协议 (例如 HTTP / TCP/IP)达成一致,并在 需要时提供额外的澄清。

1.3.2 句法 互操作性

句法互操作性通常 与数据格式和编码以及 压缩这些格式和编码的技术相关。WoT 中这些格式 和编码的示例包括 JSON、XML、JSON-LD、UTF-8 载荷。

1.3.3 语义 互操作性

语义互操作性与通信 参与方行为的共同理解相关。在配置文件上下文中, 它包括对(同步和异步)动作 语义的共同解释、共同的事件模型、如何设置/获取多个 属性、可写属性、共同的错误模型和 错误消息。

特定领域的本体,例如汽车和医疗设备的 语义互操作,超出了本 规范的范围。

1.3.4 组织 互操作性

在配置文件上下文中,组织互操作性 意味着任何符合给定配置文件的 消费者,都可以与任何符合 相同配置文件的 Thing 交互,而无需额外 定制。

组织互操作性还要求在安全、信任和隐私方面 采用共同商定的方法,即只有在应用这些共同条款和 条件时,才向 消费者提供 对 Things 的访问。

由各种工程师、厂商和 SDO 创建的设备, 只要满足配置文件规范的要求, 就可以与合规的消费者集成,而无需额外 定制。这可以跨基础设施、地区 和文化发挥作用。

2. 合规性

除标记为非规范性的章节外,本规范中的所有编写 指南、图示、示例和注释均为非规范性。 本规范中的其他所有内容均为 规范性。

本文档中的关键词 MAYMUSTMUST NOTOPTIONALRECOMMENDEDSHOULDSHOULD NOT 只有在如 此处所示全部以大写形式出现时,才应 按照 BCP 14 [RFC2119] [RFC8174] 所述进行解释。

Thing消费者 实现如果遵循本文档中的规范性陈述, 则符合本规范。

3. 术语

基本 WoT 术语,例如 Web ThingThing)、 消费者Thing Description属性动作事件协议 绑定,在 WoT Architecture 规范的第 3 节中定义 [wot-architecture11]。

3.1 附加定义

配置文件
一份技术规范,它提供了一组 断言,使得任何符合这些断言的 消费者,都可以与任何同样符合 这些断言的Thing 开箱即用地 互操作

4. 配置文件机制

为了符合某个配置文件Web Thing MUST 符合该配置文件 规范中的所有规范性陈述。

为了表示给定的 Web Thing 符合 一个或多个配置文件, 其 Thing Description MUST 包含一个 profile 成员 [wot-thing-description11]。 profile 成员的 值 MUST 设置为一个有效 URI [RFC3986], 用于标识单个配置文件, 或设置为一个有效 URI 数组,用于标识多个配置文件

为了在 Thing Description 中使用 profile 成员,@context 成员 MUST 包含 anyURI https://www.w3.org/2022/wot/td/v1.1,以 表示该文档正在使用 Thing Description 规范的 1.1 版本。[wot-thing-description11]。

{
  "@context": "https://www.w3.org/2022/wot/td/v1.1",
  "id": "urn:dev:ops:32473-WoTLamp-1234",
  "profile": "https://www.w3.org/2022/wot/profile/http-basic/v1",
  "title": "My Lamp",
  "description": "A web connected lamp",
  ...
}
{
  "@context": "https://www.w3.org/2022/wot/td/v1.1",
  "id": "urn:dev:ops:32473-WoTLamp-1234",
  "profile": [
    "https://www.w3.org/2022/wot/profile/http-basic/v1",
    "https://www.w3.org/2022/wot/profile/http-sse/v1"
  ],
  "title": "My Lamp",
  "description": "A web connected lamp",
  ...
}

所有符合某个 配置文件Things消费者 MUST 满足 WoT Thing Description 1.1 规范 [wot-thing-description11] 中规定的断言,但文本为“TD 1.1 consumers MUST accept TDs satisfying the W3C WoT Thing Description 1.0 [wot-thing-description] specification.”的断言除外。

配置文件 SHOULD NOT 重新定义协议 绑定模板 [wot-binding-templates] 中的默认值。 例如,如果某个配置文件使用 HTTP 协议绑定,并且 HTTP Binding Template 指定在 HTTP 协议绑定中, readproperty 操作的 htv:methodName 默认值为 GET,则该 配置文件不应将该值重新定义为 POST

配置文件 SHOULD NOT 要求 Thing 以一种未实现该 配置文件消费者 会感到意外的方式响应。例如,配置文件可以为 queryaction 操作定义协议绑定的细节, 这些细节目前可能无法使用 Thing Description 中的 协议绑定模板完整描述(这是由于 WoT Thing Description 1.1 规范当前的限制),并且可以由合规的 消费者 使用;但 Thing Description 暴露的任何其他 与动作相关的操作,仍应以未实现该配置文件的 消费者所期望的方式响应。

符合某个配置文件并不阻止 Web Thing 在其 Thing Description 中描述超出该配置文件所描述范围的其他能力和协议绑定, 只要它们符合该配置文件 的所有规范性断言即可。

仅仅因为某个Thing Description 声称其所描述的 Thing 符合给定的 配置文件消费者也不应假定 它实际上符合。例如,如果某个 Thing 未按规定 对给定操作作出响应,消费者应能够 优雅地恢复。

5. 通用约束

以下章节适用于本文档定义的 配置文件。

5.1 单位

Thing Descriptions 的作者应注意,其所在 地理区域常用的单位并不具有全球适用性,并且可能导致 具有严重后果的误解。

如果 一个值具有物理量,则高度 RECOMMENDED 提供 unit

对于用于全球 部署的设备,高度 RECOMMENDED 使用公制系统(SI 单位)。

5.2 日期 格式

除非另有 指定,所有日期和时间值 MUST 使用 [RFC3339] 中定义的 date-time 格式。

2022-09-21T23:20:50.52Z

为了减少歧义,RFC 3339 只 允许小时值在 00 到 23 之间(不包括 24), 并且时区表示为相对于 UTC 的数字偏移。 后缀“Z”应用于时间时表示 UTC 偏移为 00:00。

5.3 安全

合规的 Web Things MUST 使用以下至少一种 安全方案 [wot-thing-description11]:

  • NoSecurityScheme
  • BasicSecurityScheme
  • 带有 codeclient 流程的 OAuth2SecurityScheme

合规的消费者 MUST 支持以下所有 安全方案 [wot-thing-description11]:

  • NoSecurityScheme
  • BasicSecurityScheme
  • 带有 codeclient 流程的 OAuth2SecurityScheme
  • oneOf 成员至少包含上述一种 方案的 ComboSecurityScheme

Thing MAY 实现多个安全方案。

如果某个 Thing 支持多个 安全方案,则它 MUST 使用 ComboSecurityScheme 通过 oneOf 成员枚举这些方案,使得一次只需要使用一个 安全方案。

对于 BasicSecurityScheme,“in”字段 MUST 要么省略, 要么被赋予 [wot-thing-description11] 中定义的默认 值“header”。 对于 BasicSecurityScheme,如果未给出“proxy”端点, “name”字段 MUST 使用值 “Authorization”提供。 对于 BasicSecurityScheme,如果给出了“proxy”端点, “name”字段 MUST 使用值 “Proxy-Authorization”提供。

合规的消费者 MUST 支持所有已实现安全方案的 安全引导,如 WoT Discovery [wot-discovery] 规范中安全 引导所定义。

合规的Things 如果需要 身份验证才能检索其 Thing Description,则 MUST 实现 安全引导,如 WoT Discovery [wot-discovery] 规范中安全 引导所定义。

5.4 发现

Web ThingThing Description [wot-thing-description11] MUST 可通过由直接 引入机制 [wot-discovery] 提供的 HTTP URL [RFC9110],从 Thing Description Server [wot-architecture11] 检索。

5.6 错误

如果 HTTP 配置文件的协议绑定中定义的任何操作 未成功,则 Web Thing MUST 发送一个带有 HTTP 错误 代码的 HTTP 响应,该错误代码描述失败原因。

错误响应 RECOMMENDED 使用以下 HTTP 错误代码之一:

  • 400 Bad Request
  • 401 Unauthorized
  • 403 Forbidden
  • 404 Not Found
  • 500 Internal Server Error
  • 503 Service Unavailable

Web Thing MAY 出于 重定向、缓存或身份验证目的,以 3xx 状态码 响应。 Web Thing MUST NOT300 Multiple Choices 状态码响应。

Web Things MAY 以其他有效的 HTTP 错误代码 响应(例如 418 I'm a teapot)。 消费者 MAY 将其他有效的 HTTP 错误代码解释为 一个通用的 4xx5xx 错误,而不赋予 特殊定义的行为。

如果 HTTP 错误响应 包含主体,则该主体的内容 MUST 符合 Problem Details 格式 [RFC7807]。

6. HTTP Basic Profile

本节定义 HTTP Basic Profile,其中包括一个 协议 绑定,用于读取和写入属性,以及调用、 查询和取消动作。

此配置文件可以与 HTTP SSE ProfileHTTP Webhook Profile 一起使用,以便 提供用于观察属性和侦听 事件的操作。

为了 符合 HTTP Basic Profile,Web Things 和 消费者 MUST 还必须符合 通用约束 一节中的所有断言。

6.1 标识符

为了表示给定的 Web Thing 符合 HTTP Basic Profile,其 Thing Description MUST 具有一个 profile 成员 [wot-thing-description11], 其值为 https://www.w3.org/2022/wot/profile/http-basic/v1

6.2 协议绑定

本节定义一个协议绑定,它 描述消费者如何使用通过 HTTP 协议 [RFC9112] 传输的 JSON [JSON] 载荷,与 Web Thing [wot-architecture11] 通信。

符合 HTTP Basic Profile 的消费者Web Thing MUST 实现 此协议绑定。

本节中提供的示例描述了 消费者会如何与产生以下 Thing DescriptionWeb Thing 通信:

{
  "@context": "https://www.w3.org/2022/wot/td/v1.1",
  "id": "https://mywebthingserver.com/things/lamp",
  "profile": "https://www.w3.org/2022/wot/profile/http-basic/v1",
  "base": "https://mywebthingserver.com/things/lamp/",
  "title": "My Lamp",
  "description": "A web connected lamp",
  "securityDefinitions": {
    "oauth2": {
      "scheme": "oauth2",
      "flow": "code",
      "authorization": "https://mywebthingserver.com/oauth/authorize",
      "token": "https://mywebthingserver.com/oauth/token"
    }
  },
  "security": "oauth2",
  "properties": {
    "on": {
      "type": "boolean",
      "title": "On/Off",
      "description": "Whether the lamp is turned on",
      "forms": [{"href": "properties/on"}]
    },
    "level" : {
      "type": "integer",
      "title": "Brightness",
      "description": "The level of light from 0-100",
      "unit": "percent",
      "minimum" : 0,
      "maximum" : 100,
      "forms": [{"href": "properties/level"}]
    }
  },
  "actions": {
    "fade": {
      "title": "Fade",
      "description": "Fade the lamp to a given level",
      "synchronous": false,
      "input": {
        "type": "object",
        "properties": {
          "level": {
            "title": "Brightness",
            "type": "integer",
            "minimum": 0,
            "maximum": 100,
            "unit": "percent"
          },
          "duration": {
            "title": "Duration",
            "type": "integer",
            "minimum": 0,
            "unit": "milliseconds"
          }
        }
      },
      "forms": [{"href": "actions/fade"}]
    }
  },
  "forms": [
    {
      "op": ["readallproperties", "writemultipleproperties"],
      "href": "properties"
    },
    {
      "op": "queryallactions",
      "href": "actions"
    }
  ]
}

6.2.1 属性

6.2.1.1 readproperty

读取属性值时使用的属性资源 URL MUST 通过在 Thing Description 中定位对应 PropertyAffordance 内满足以下条件的 Form 来获得:

  • 应用默认值后,其 op 成员包含值 readproperty
  • 在适用时相对于基 URL 解析后, 其 href 成员值的 URI scheme [RFC3986] 为 httphttps
  • 应用默认值后,其 contentType 成员的值为 application/json

href 成员解析后的值随后 MUST 用作 属性资源的 URL。

为了读取属性的值, 消费者 MUSTWeb Thing 发送具有以下内容的 HTTP 请求:

  • 方法设置为 GET
  • URL 设置为属性资源的 URL
  • Accept 标头设置为 application/json
GET /things/lamp/properties/on HTTP/1.1
Host: mythingserver.com
Accept: application/json

如果 Web Thing 收到符合上述格式的 HTTP 请求,并且 消费者有权限 读取对应的属性,则在 成功读取该属性的值后, 它 MUST 发送具有以下内容的 HTTP 响应:

  • 状态码设置为 200
  • Content-Type 标头设置为 application/json
  • 主体包含以 JSON 序列化的 属性值
HTTP/1.1 200 OK
Content-Type: application/json
false
6.2.1.2 writeproperty

写入属性值时使用的属性资源 URL MUST 通过在 Thing Description 中定位对应 PropertyAffordance 内满足以下条件的 Form 来获得:

  • 应用默认值后,其 op 成员包含值 writeproperty
  • 在适用时相对于基 URL 解析后, 其 href 成员值的 URI scheme [RFC3986] 为 httphttps
  • 应用默认值后,其 contentType 成员的值为 application/json

href 成员解析后的值随后 MUST 用作 属性资源的 URL。

为了写入属性的值, 消费者 MUSTWeb Thing 发送具有以下内容的 HTTP 请求:

  • 方法设置为 PUT
  • URL 设置为属性资源的 URL
  • Content-Type 标头设置为 application/json
  • 主体包含以 JSON 序列化的 属性请求新值
PUT /things/lamp/properties/on HTTP/1.1
Host: mythingserver.com
Content-Type: application/json
true

如果 Web Thing 收到符合上述格式的 HTTP 请求,并且 消费者有权限 写入对应的属性,则在 成功写入该属性的值后,它 MUST 发送具有以下内容的 HTTP 响应:

  • 状态码设置为 204
HTTP/1.1 204 No Content
6.2.1.3 readallproperties

一次性读取所有属性值时使用的 properties 资源 URL MUST 通过在 Thing Description 的顶层 forms 成员中定位满足以下条件的 Form 来获得:

  • op 成员包含值 readallproperties
  • 在适用时相对于基 URL 解析后, 其 href 成员值的 URI scheme [RFC3986] 为 httphttps
  • 应用默认值后,其 contentType 成员的值为 application/json

href 成员解析后的值 随后 MUST 用作 properties 资源的 URL。

为了读取所有属性的值, 消费者 MUSTWeb Thing 发送具有以下内容的 HTTP 请求:

  • 方法设置为 GET
  • URL 设置为 properties 资源的 URL
  • Accept 标头设置为 application/json
GET /things/lamp/properties HTTP/1.1
Host: mythingserver.com
Accept: application/json

如果 Web Thing 收到符合上述格式的 HTTP 请求,则在成功读取 消费者有权限 访问的所有可读属性的值后, 它 MUST 发送具有以下内容的 HTTP 响应:

  • 状态码设置为 200
  • Content-Type 标头设置为 application/json
  • 主体包含所有可读属性的值,这些值以 JSON 序列化为一个以属性名为键的对象
HTTP/1.1 200 OK
Content-Type: application/json
{
  "on": false,
  "level": 100
}
6.2.1.4 writemultipleproperties

一次性写入多个属性值时使用的 properties 资源 URL MUST 通过在 Thing Description 的顶层 forms 成员中定位满足以下条件的 Form 来获得:

  • op 成员包含值 writemultipleproperties
  • 在适用时相对于基 URL 解析后, 其 href 成员值的 URI scheme [RFC3986] 为 httphttps
  • 应用默认值后,其 contentType 成员的值为 application/json

href 成员解析后的值 随后 MUST 用作 properties 资源的 URL。

为了一次性写入多个属性的值, 消费者 MUSTWeb Thing 发送具有以下内容的 HTTP 请求:

  • 方法设置为 PUT
  • URL 设置为属性资源的 URL
  • Content-Type 标头设置为 application/json
  • 主体包含可写 属性的请求新值,这些值以 JSON 序列化为一个以属性名为键的对象
PUT /things/lamp/properties HTTP/1.1
Host: mythingserver.com
Content-Type: application/json
{
  "on": true,
  "level": 50
}

如果 Web Thing 收到符合上述格式的 HTTP 请求,则在成功写入 所请求的可写属性的值后,它 MUST 发送 具有以下内容的 HTTP 响应:

  • 状态码设置为 204
HTTP/1.1 204 No Content

排除 readmultipleproperties 操作是因为请求载荷格式较为复杂, 并且与 readpropertyreadallproperties 相比并没有增加多少 功能。 writeallproperties 被排除,是因为它 只是 writemultipleproperties 的一个特殊情况。

6.2.2 动作

6.2.2.1 invokeaction

调用动作时使用的动作资源 URL MUST 通过在 Thing Description 中定位对应 ActionAffordance 内满足以下条件的 Form 来获得:

  • 应用默认值后,其 op 成员的值为 invokeaction
  • 在适用时相对于基 URL 解析后, 其 href 成员值的 URI scheme [RFC3986] 为 httphttps
  • 应用默认值后,其 contentType 成员的值为 application/json

href 成员解析后的值 MUST 随后用作 动作资源的 URL。

为了在 Web Thing 上调用 动作消费者 MUSTWeb Thing 发送具有以下内容的 HTTP 请求:

  • 方法设置为 POST
  • URL 设置为动作资源的 URL
  • Accept 标头设置为 application/json
  • Content-Type 标头设置为 application/json(仅当该动作具有 输入时)
  • 主体包含动作的输入(如有), 以 JSON 序列化
POST /things/lamp/actions/fade HTTP/1.1
Host: mythingserver.com
Content-Type: application/json
Accept: application/json
{
  "level": 100,
  "duration": 5
}

如果 动作没有输入,则请求的 Content-type 标头 SHOULD NOT 设置,并且主体 should 为空。

有效的 JSON 值——例如 null、空引号 ("")或空花括号({})—— 可能是有效的动作输入,并不被认为是 “空”主体。

如果 Web Thing 收到符合上述格式的 HTTP 请求,则它 MUST 以下列三种响应格式之一进行 响应:

  1. 同步动作 响应
  2. 异步 动作响应
  3. 错误响应

ActionAffordancesynchronous 成员 MUST 设置 为 truefalse

如果 ActionAffordance [wot-thing-description11] 的 synchronous 成员设置为 true,则 Web Thing MUST同步动作 响应进行响应。

如果 ActionAffordance [wot-thing-description11] 的 synchronous 成员设置为 false,则 Web Thing MUST异步 动作 响应进行响应。

对于 不预期在 HTTP 请求超时期限内 (例如 30 到 120 秒)完成执行的长时间运行动作, Web Thing RECOMMENDED 以 异步动作响应进行响应,以便 消费者可以在初始 invokeaction 响应之后,继续通过对动态 创建的 ActionStatus 资源执行 queryaction 操作来监视动作请求的 状态。

对于 预期在 HTTP 请求超时期限内完成执行的 短时动作, Web Thing MAY 等待该 动作完成后再发送同步动作 响应。

如果 Web Thing 在响应 invokeaction 请求之前尝试执行动作时遇到错误, 则它 MUST 发送 错误响应。

合规的 消费者 MUST 支持对初始 invokeaction 请求的所有三种 响应类型。 初始 请求之后,对 ActionStatus 资源上的后续操作的支持 是 OPTIONAL

6.2.2.1.1 ActionStatus 对象

异步动作调用 请求的状态由 ActionStatus 对象表示,该对象包含以下 成员:

成员 描述 赋值 类型
status 动作请求的状态。 必需 string(以下之一: pendingrunningcompletedfailed
output 已完成动作的输出数据(如有),该数据 MUST 符合对应 ActionAffordanceoutput 数据 模式。 可选 任意类型
error 与失败动作关联的错误消息(如有),它 MUST 使用 Problem Details 格式的 JSON 序列化 [RFC7807] (仅在响应 queryaction 操作时需要)。 可选 object
href 可由 queryactioncancelaction 操作使用的 ActionStatus 资源的 [URL], 其 URI scheme [RFC3986] MUST 解析为 httphttps(仅在 异步 动作响应中需要)。 可选 string
timeRequested 一个时间戳,指示 Thing 收到执行 动作请求的时间。(有关日期格式约束,参见日期 格式)。 可选 string
timeEnded 一个时间戳,指示 Thing 成功 完成执行该动作,或执行该动作失败的时间。 (有关日期格式约束,参见日期格式)。 可选 string

某个 Thing 的时钟可能没有 设置为正确时间。如果时间很重要, 则消费者因此可以 选择将 ActionStatus 对象的 timeEnded 成员视为相对于 timeRequested 成员,但不一定 相对于其自身内部时钟,或其他 Things 的时钟。

6.2.2.1.2 同步动作 响应

如果为具有输出的动作提供同步动作响应, Web Thing MUST 发送具有以下内容的 HTTP 响应:

  • 状态码设置为 200
  • Content-Type 标头设置为 application/json
  • 主体包含该动作的输出, 以 JSON 序列化
示例 14:带有 输出的同步动作响应
HTTP/1.1 200 OK
Content-Type: application/json
20

如果为没有输出的动作提供同步动作响应, Web Thing MUST 发送具有以下内容的 HTTP 响应:

  • 状态码设置为 204
  • Content-Type 标头未设置
  • 空主体
示例 15:没有输出的同步动作响应
HTTP/1.1 204 No Content

有效的 JSON 值——例如 null、空引号 ("")或空花括号({}) ——可能是有效的动作输出,并不 被认为是“空”主体。

6.2.2.1.3 异步动作 响应

如果提供异步动作响应, Web Thing MUST 发送包含 ActionStatus 资源 URL 的 HTTP 响应, 该 URL 的 URI scheme [RFC3986] MUST 解析为 httphttps。该响应 MUST 具有:

  • 状态码设置为 201
  • Content-Type 标头设置为 application/json
  • Location 标头设置为 ActionStatus 资源的 URL
  • 主体包含一个以 JSON 序列化的 ActionStatus 对象,其 href 成员设置为 ActionStatus 资源的 URL
HTTP/1.1 201 CREATED
Content-Type: application/json
Location: /things/lamp/actions/fade/123e4567-e89b-12d3-a456-426655
{
  "status": "pending",
  "href": "/things/lamp/actions/fade/123e4567-e89b-12d3-a456-426655",
  "timeRequested": "2021-11-10T11:43:19.135Z"
}

在资源受限的环境中,较旧的 已完成/已失败动作的 ActionStatus 对象 MAY 被删除,以便为新调用的 动作腾出空间。

如果由于动作不可用而不能接受调用, 例如因为 Thing 过载, 则 Web Thing SHOULD 返回 503 错误 响应。

6.2.2.2 queryaction

queryaction 操作用于查询 正在进行的动作请求的当前状态。

动作上的 invokeaction 操作提供 异步动作 响应Web Thing MUST 还支持在该同一 动作上的 queryaction 操作。 仅对 动作上的 invokeaction 操作提供 同步动作 响应Web Thing SHOULD NOT 支持在该同一 动作上的 queryaction 操作。

queryaction 操作中使用的 ActionStatus 资源 URL MUST异步动作 响应Location 标头,或其主体中 ActionStatus 对象的 href 成员获得。

为了查询动作请求的状态, 消费者 MUSTWeb Thing 发送具有以下内容的 HTTP 请求:

  • 方法设置为 GET
  • URL 设置为 ActionStatus 资源的 URL
  • Accept 标头设置为 application/json
GET /things/lamp/actions/fade/123e4567-e89b-12d3-a456-426655
Host: mythingserver.com
Accept: application/json

如果 Web Thing 收到符合上述格式的 HTTP 请求,并且 消费者有权限 查询对应的 ActionStatus 资源,则在成功读取该动作请求的状态后, 它 MUST 发送具有以下内容的 HTTP 响应:

  • 状态码设置为 200
  • Content-Type 标头设置为 application/json
  • 主体包含一个 ActionStatus 对象,表示动作请求的当前状态, 并以 JSON 序列化
HTTP/1.1 200 OK
Content-Type: application/json
{
  "status": "running",
  "timeRequested": "2021-11-10T11:43:19.135Z"
}

如果 被查询的动作执行失败,则 ActionStatus 对象的 status 成员 MUST 设置为 "failed" 如果 被查询的动作执行失败,则 error 成员 MAY 提供符合 Problem Details 格式的 其他错误信息 [RFC7807]。

HTTP/1.1 200 OK
Content-Type: application/json
{
  "status": "failed",
  "error": {
    "type": "https://mythingserver.com/docs/errors/invalid-level",
    "title": "Invalid value for level provided",
    "invalid-params": [
      {
        "name": "level",
        "reason": "Must be a valid number between 0 and 100"
      }
    ]
  },
  "timeRequested": "2021-11-10T11:43:19.135Z",
  "timeEnded": "2021-11-10T11:43:20.513Z"
}
6.2.2.3 cancelaction

cancelaction 操作用于 取消正在进行的动作请求。

动作上的 invokeaction 操作提供 异步动作 响应Web Thing MAY 还支持在该同一 动作上的 cancelaction 操作。 仅对 动作上的 invokeaction 操作提供 同步动作 响应Web Thing SHOULD NOT 支持在该同一 动作上的 cancelaction 操作。

cancelaction 操作中使用的 ActionStatus 资源 URL MUST异步动作 响应Location 标头,或其主体中 ActionStatus 对象的 href 成员获得。

为了取消动作请求, 消费者 MUSTWeb Thing 发送具有以下内容的 HTTP 请求:

  • 方法设置为 DELETE
  • URL 设置为 ActionStatus 资源的 URL
DELETE /things/lamp/actions/fade/123e4567-e89b-12d3-a456-426655 HTTP/1.1
Host: mythingserver.com

如果 Web Thing 收到符合上述格式的 HTTP 请求,并且 消费者有权限 取消对应的动作请求,则在成功 取消该动作后,它 MUST 发送具有以下内容的 HTTP 响应:

  • 状态码设置为 204
HTTP/1.1 204 No Content
6.2.2.4 queryallactions

查询所有正在进行的动作请求状态时使用的 actions 资源 URL MUST 通过在 Thing Description 的顶层 forms 成员中定位满足以下条件的 Form 来获得:

  • op 成员包含值 queryallactions
  • 在适用时相对于基 URL 解析后, 其 href 成员值的 URI scheme [RFC3986] 为 httphttps
  • 应用默认值后,其 contentType 成员的值为 application/json

href 成员解析后的值 MUST 随后用作 actions 资源的 URL。

为了查询所有正在进行的动作 请求的状态,消费者 MUSTWeb Thing 发送具有以下内容的 HTTP 请求:

  • 方法设置为 GET
  • URL 设置为 actions 资源的 URL
  • Accept 标头设置为 application/json
GET /things/lamp/actions HTTP/1.1
Host: mythingserver.com
Accept: application/json

如果 Web Thing 收到符合上述格式的 HTTP 请求,则在成功检索 消费者有 权限访问的所有正在进行的动作请求的状态后, 它 MUST 发送具有以下内容的 HTTP 响应:

  • 状态码设置为 200
  • Content-Type 标头设置为 application/json
  • 主体包含一个对象,该对象以 动作名称为键, 每个对象成员的值是一个 ActionStatus 对象数组, 用于表示动作请求,并以 JSON 序列化。

结果 对象中的每个数组 MUST 按逆时间顺序排序,使得 最近的动作请求首先出现。

HTTP/1.1 200 OK
Content-Type: application/json
{
  "fade": [
    {
      "status": "completed",
      "href": "/things/lamp/actions/fade/123e4567-e89b-12d3-a456-426655",
      "timeRequested": "2021-11-10T11:43:19.135Z",
      "timeEnded": "2021-11-10T11:43:20.513Z"
    },
    {
      "status": "failed",
      "href": "/things/lamp/actions/fade/123e4567-e89b-12d3-a456-558329",
      "timeRequested": "2021-11-10T11:42:15.133Z",
      "timeEnded": "2021-11-10T11:42:22.524Z"
    },
    {
      "status": "running",
      "href": "/things/lamp/actions/fade/123e4567-e89b-12d3-a457-434656",
      "timeRequested": "2021-11-10T11:41:53.351Z"
    },
    {
      "status": "pending",
      "href": "/things/lamp/actions/fade/123e4567-e89b-12d3-a457-ea9519",
      "timeRequested": "2021-11-10T11:39:53.651Z"
    }
  ]
}
:ActionStatus 对象的 保留
当动作请求通过 cancelaction 操作取消时,其 ActionStatus 对象会被删除,并且无需 保留。对于所有其他动作请求,假定 Web Thing 会存储 ActionStatus 对象,以便之后可以通过 queryactionqueryallactions 操作查询其状态。 并不期望 ActionStatus 对象应 无限期保留;它们可以存储在 易失性内存中,并/或定期修剪。保留 ActionStatus 对象的时间长度预计是实现特定的,并且 可能取决于特定应用需求或 资源约束。

7. HTTP SSE Profile

本节定义 HTTP SSE Profile,其中包括一个 协议 绑定,用于使用服务器发送事件 [EVENTSOURCE] 观察属性并侦听 事件

此配置文件可以与 HTTP Basic Profile 一起使用, 以便提供读取和写入属性以及调用、 查询和取消动作的操作。

为了 符合 HTTP SSE Profile,Web Things消费者 MUST 还必须符合 通用约束 一节中的所有断言。

7.1 标识符

为了表示给定的 Web Thing 符合 HTTP SSE Profile,其 Thing Description MUST 具有一个 profile 成员 [wot-thing-description11], 其值为 https://www.w3.org/2022/wot/profile/http-sse/v1

7.2 协议绑定

本节定义一个协议绑定,它 描述消费者如何使用服务器发送事件 [EVENTSOURCE] 与 Web Thing [wot-architecture11] 通信。

符合 HTTP SSE Profile 的消费者Web Thing MUST 实现此 协议绑定。

本节中提供的示例描述了 消费者会如何与产生以下 Thing DescriptionWeb Thing 通信:

{
  "@context": "https://www.w3.org/2022/wot/td/v1.1",
  "id": "https://mywebthingserver.com/things/lamp",
  "profile": "https://www.w3.org/2022/wot/profile/http-sse/v1",
  "base": "https://mywebthingserver.com/things/lamp/",
  "title": "My Lamp",
  "description": "A web connected lamp",
  "securityDefinitions": {
    "oauth2": {
      "scheme": "oauth2",
      "flow": "code",
      "authorization": "https://mywebthingserver.com/oauth/authorize",
      "token": "https://mywebthingserver.com/oauth/token"
    }
  },
  "security": "oauth2",
  "properties": {
    "on": {
      "type": "boolean",
      "title": "On/Off",
      "description": "Whether the lamp is turned on",
      "forms": [
        {
          "href": "properties/on",
          "op": ["observeproperty", "unobserveproperty"],
          "subprotocol": "sse"
        }
      ]
    },
    "level" : {
      "type": "integer",
      "title": "Brightness",
      "description": "The level of light from 0-100",
      "unit": "percent",
      "minimum" : 0,
      "maximum" : 100,
      "forms": [
        {
          "href": "properties/level",
          "op": ["observeproperty", "unobserveproperty"],
          "subprotocol": "sse"
        }
      ]
    }
  },
  "events": {
    "overheated": {
      "title": "Overheated",
      "data": {
        "type": "number",
        "unit": "degree celsius"
      },
      "description": "The lamp has exceeded its safe operating temperature",
      "forms": [{
        "href": "events/overheated",
        "subprotocol": "sse"
      }]
    }
  },
  "forms": [
    {
      "op": ["observeallproperties", "unobserveallproperties"],
      "href": "properties",
      "subprotocol": "sse"
    },
    {
      "op": ["subscribeallevents", "unsubscribeallevents"],
      "href": "events",
      "subprotocol": "sse"
    }
  ]
}

7.2.1 属性

7.2.1.1 observeproperty

观察属性值时使用的属性资源 URL MUST 通过在 Thing Description 中定位对应 PropertyAffordance 内满足以下条件的 Form 来获得:

  • op 成员包含值 observeproperty
  • 在适用时相对于基 URL 解析后, 其 href 成员值的 URI scheme [RFC3986] 为 httphttps
  • subprotocol 成员的值 为 sse
  • 应用默认值后,其 contentType 成员的值为 application/json

href 成员解析后的值随后 MUST 用作 属性资源的 URL。

为了 观察属性消费者 MUST 遵循服务器发送事件 [EVENTSOURCE] 规范,在属性资源的 URL 处与 Web Thing 打开连接。

这涉及消费者Web Thing 发送具有以下内容的 HTTP 请求:

  • 方法设置为 GET
  • URL 设置为属性资源的 URL
  • Accept 标头设置为 text/event-stream
  • Connection 标头设置为 keep-alive
GET /things/lamp/properties/level HTTP/1.1
Host: mythingserver.com
Accept: text/event-stream
Connection: keep-alive
:使用 JavaScript 打开连接

对于使用 JavaScript [ECMASCRIPT] 实现并在暴露 EventSource 接口的运行时中执行的消费者, 可以使用 EventSource 构造函数发起服务器发送 事件连接。

const levelSource = new EventSource('/things/lamp/properties/level');

如果 Web Thing 收到符合上述格式的 HTTP 请求,并且 消费者有权限 观察对应的属性,则它 MUST 遵循服务器发送事件 [EVENTSOURCE] 规范,与 消费者保持打开的连接,并在指定 属性 的值每次变化时,将属性值推送给 消费者

这涉及 Web Thing 首先向 消费者发送具有以下内容的 HTTP 响应:

  • 状态码设置为 200
  • Content-Type 标头设置为 text/event-stream
HTTP/1.1 200 OK
Content-Type: text/event-stream

只要指定 属性的值在 Web Thing消费者之间存在打开连接期间发生变化, Web Thing MUST 使用服务器发送事件 [EVENTSOURCE] 规范中的事件流格式向 消费者发送属性值。 对于 发送的每条消息,Web Thing MUSTevent 字段设置为 PropertyAffordance 的名称,并用以 JSON 序列化且 遵循 PropertyAffordance 中指定的数据模式的属性值填充 data 字段。 id 字段 SHOULD 设置为属性变化的唯一标识符, 以便在重新建立断开的连接时使用(见下文)。 RECOMMENDED 该标识符是一个表示属性变化发生时间的时间戳(有关日期格式约束,参见 日期格式)。

event: level\n
data: 42\n
id: 2021-11-17T15:33:20.827Z\n\n

如果 消费者Web Thing 之间的连接断开(除非是由于下面定义的 unobserve 操作所致), 消费者 MUST 按照 服务器发送事件规范 [EVENTSOURCE] 中列出的步骤重新建立连接。 连接 重新建立后,Web Thing SHOULD 在可能的情况下,发送自 消费者Last-Event-ID 标头中指定的最后一次变化以来发生的任何遗漏的 属性变化。

: 包装在 text/event-stream 中的 application/json

属性值以 JSON 序列化,并在 以 text/event-stream 格式序列化的服务器发送事件的 data 字段中提供。 HTTP 标头中使用的 text/event-stream 内容类型 被假定由 sse 子协议隐含,而嵌入的 application/json 内容类型则在 Form 的 contentType 成员中指明(应用默认值后)。

7.2.1.2 unobserveproperty

为了 停止观察属性消费者 MUST 按服务器发送事件规范 [EVENTSOURCE] 的规定,终止与 Web Thing 的对应 服务器发送事件连接。

: 使用 JavaScript 终止连接

对于使用 JavaScript [ECMASCRIPT] 实现并在暴露 EventSource 接口的运行时中执行的 消费者, 可以使用 EventSource [EVENTSOURCE] 对象上的 close() 方法终止服务器发送 事件连接。

levelSource.close();
7.2.1.3 observeallproperties

观察某个 Web Thing 的所有属性变化时使用的 properties 资源 URL MUST 通过在 Thing Description 的顶层 forms 成员中定位满足以下条件的 Form 来获得:

  • op 成员包含值 observeallproperties
  • 在适用时相对于基 URL 解析后, 其 href 成员值的 URI scheme [RFC3986] 为 httphttps
  • subprotocol 成员的值 为 sse
  • 应用默认值后,其 contentType 成员的值为 application/json

href 成员解析后的值 随后 MUST 用作 properties 资源的 URL。

为了观察 Web Thing 的所有属性变化, 消费者 MUST 遵循服务器发送事件 [EVENTSOURCE] 规范,在 properties 资源的 URL 处与 Web Thing 打开连接。

这涉及消费者Web Thing 发送具有以下内容的 HTTP 请求:

  • 方法设置为 GET
  • URL 设置为 properties 资源的 URL
  • Accept 标头设置为 text/event-stream
  • Connection 标头设置为 keep-alive
GET /things/lamp/properties HTTP/1.1
Host: mythingserver.com
Accept: text/event-stream
Connection: keep-alive
:使用 JavaScript 打开连接

对于使用 JavaScript [ECMASCRIPT] 实现并在暴露 EventSource 接口的运行时中执行的 消费者, 可以使用 EventSource 构造函数发起服务器发送 事件连接。

const lampPropertiesSource = new EventSource('/things/lamp/properties');

如果 Web Thing 收到符合上述格式的 HTTP 请求,则它 MUST 遵循 服务器发送事件 [EVENTSOURCE] 规范,与 消费者保持打开的连接,并向 消费者推送其有权限观察的所有 属性的新 属性值。

这涉及 Web Thing 首先向 消费者发送具有以下内容的 HTTP 响应:

  • 状态码设置为 200
  • Content-Type 标头设置为 text/event-stream
HTTP/1.1 200 OK
Content-Type: text/event-stream

只要属性Web Thing 与消费者之间存在打开连接期间发生变化, Web Thing MUST 使用服务器发送事件 [EVENTSOURCE] 规范中的事件流格式向 消费者发送新的 属性值。 对于发送的每条消息,Web Thing MUSTevent 字段设置为 PropertyAffordance 的名称,并用新的属性值填充 data 字段。 属性数据 MUST 遵循 PropertyAffordance 中指定的数据模式,并且 MUST 以 JSON 序列化。 id 字段 SHOULD 设置为事件的唯一标识符,以便在 重新建立断开的连接时使用(见下文)。 RECOMMENDED 该 标识符是一个表示 属性变化发生时间的时间戳 (有关日期 格式约束,参见日期格式)。

event: level\n
data: 42\n
id: 2021-11-17T15:33:20.827Z\n\n

如果 消费者Web Thing 之间的连接断开(除非是由于下面定义的 unobserveallproperties 操作所致),消费者 MUST 按照服务器发送事件 规范 [EVENTSOURCE] 中列出的步骤重新建立连接。 连接重新建立后,Web Thing SHOULD 在可能的情况下,发送自 消费者Last-Event-ID 标头中指定的最后一次变化以来发生的任何遗漏的 属性变化。

: 包装在 text/event-stream 中的 application/json

属性值以 JSON 序列化,并在 以 text/event-stream 格式序列化的 服务器发送事件的 data 字段中提供。 HTTP 标头中使用的 text/event-stream 内容类型 被假定由 sse 子协议隐含,而嵌入的 application/json 内容类型则在 Form 的 contentType 成员中指明(应用 默认值后)。

7.2.1.4 unobserveallproperties

为了取消观察所有属性,消费者 MUST 按照服务器发送事件规范 [EVENTSOURCE] 中指定的步骤,终止与 Web Thing 的 properties 端点之间的对应服务器发送事件连接。

: 使用 JavaScript 终止连接

对于使用 JavaScript [ECMASCRIPT] 实现并在暴露 EventSource 接口的运行时中执行的 消费者, 可以使用 EventSource [EVENTSOURCE] 对象上的 close() 方法终止服务器发送 事件连接。

lampPropertiesSource.close();

7.2.2 事件

HTTP SSE Profile 使用服务器发送事件 [EVENTSOURCE] 作为一种机制, 使消费者能够订阅由 Web Thing 发出的事件。

消费者不需要 实现服务器发送事件规范中的 EventSource JavaScript API,也可以符合 此配置文件。任何编程语言都可以用于 消费事件流。

7.2.2.1 subscribeevent

订阅事件时使用的事件资源 URL MUST 通过在 Thing Description 中定位对应 EventAffordance 内满足以下条件的 Form 来获得:

  • 应用默认值后,其 op 成员包含值 subscribeevent
  • 在适用时相对于基 URL 解析后, 其 href 成员值的 URI scheme [RFC3986] 为 httphttps
  • subprotocol 成员的值 为 sse
  • 应用默认值后,其 contentType 成员的值为 application/json

href 成员解析后的值随后 MUST 用作 事件资源的 URL。

为了 订阅事件消费者 MUST 遵循服务器发送事件 [EVENTSOURCE] 规范,在事件资源的 URL 处与 Web Thing 打开连接。

这涉及消费者Web Thing 发送具有以下内容的 HTTP 请求:

  • 方法设置为 GET
  • URL 设置为事件资源的 URL
  • Accept 标头设置为 text/event-stream
  • Connection 标头设置为 keep-alive
GET /things/lamp/events/overheated HTTP/1.1
Host: mythingserver.com
Accept: text/event-stream
Connection: keep-alive
:使用 JavaScript 打开连接

对于使用 JavaScript [ECMASCRIPT] 实现并在暴露 EventSource 接口的运行时中执行的 消费者, 可以使用 EventSource 构造函数发起服务器发送 事件连接。

const overheatedEventSource = new EventSource('/things/lamp/events/overheated');

如果 Web Thing 收到符合上述格式的 HTTP 请求,并且 消费者有权限 订阅对应的事件,则它 MUST 遵循 服务器发送事件 [EVENTSOURCE] 规范,与 消费者保持打开的连接,并在指定类型的事件发出时 将事件数据推送给 消费者

这涉及 Web Thing 首先向 消费者发送具有以下内容的 HTTP 响应:

  • 状态码设置为 200
  • Content-Type 标头设置为 text/event-stream
HTTP/1.1 200 OK
Content-Type: text/event-stream

只要指定类型的事件在 Web Thing消费者之间存在打开连接期间发生, Web Thing MUST 使用服务器发送事件 [EVENTSOURCE] 规范中的事件流格式向 消费者发送事件数据。 对于 发送的每条消息,Web Thing MUSTevent 字段设置为 EventAffordance 的名称,并用事件数据(如有)填充 data 字段。 事件数据 MUST 遵循 EventAffordance 中指定的数据 模式,并以 JSON 序列化。 id 字段 SHOULD 设置为事件的唯一标识符, 以便在重新建立断开的连接时使用(见下文)。 RECOMMENDED 该 标识符是一个表示事件发生时间的时间戳(有关日期格式约束,参见 日期格式)。

event: overheated\n
data: 90\n
id: 2021-11-16T16:53:50.817Z\n\n

如果 消费者Web Thing 之间的连接断开(除非是由于下面定义的 unsubscribeevent 操作所致),消费者 MUST 按照服务器发送事件 规范 [EVENTSOURCE] 中列出的步骤重新建立连接。 连接 重新建立后,Web Thing SHOULD 在可能的情况下,发送自 消费者Last-Event-ID 标头中指定的最后一个事件以来发生的任何遗漏 事件。

: 包装在 text/event-stream 中的 application/json

事件载荷以 JSON 序列化,并在 以 text/event-stream 格式序列化的 服务器发送事件的 data 字段中提供。 HTTP 标头中使用的 text/event-stream 内容类型 被假定由 sse 子协议隐含,而嵌入的 application/json 内容类型则在 Form 的 contentType 成员中指明(应用 默认值后)。

7.2.2.2 unsubscribeevent

为了 取消订阅事件消费者 MUST 按服务器发送事件规范 [EVENTSOURCE] 的规定,终止与 Web Thing 的对应 服务器发送事件连接。

: 使用 JavaScript 终止连接

对于使用 JavaScript [ECMASCRIPT] 实现并在暴露 EventSource 接口的运行时中执行的 消费者, 可以使用 EventSource [EVENTSOURCE] 对象上的 close() 方法终止服务器发送 事件连接。

overheatedEventSource.close();
7.2.2.3 subscribeallevents

订阅由某个 Web Thing 发出的所有事件时使用的 events 资源 URL MUST 通过在 Thing Description 的顶层 forms 成员中定位满足以下条件的 Form 来获得:

  • op 成员包含值 subscribeallevents
  • 在适用时相对于基 URL 解析后, 其 href 成员值的 URI scheme [RFC3986] 为 httphttps
  • subprotocol 成员的值 为 sse
  • 应用默认值后,其 contentType 成员的值为 application/json

href 成员解析后的值 随后 MUST 用作 events 资源的 URL。

为了 订阅由 Web Thing 发出的所有 事件消费者 MUST 遵循 服务器发送事件 [EVENTSOURCE] 规范,在 events 资源的 URL 处与 Web Thing 打开连接。

这涉及消费者Web Thing 发送具有以下内容的 HTTP 请求:

  • 方法设置为 GET
  • URL 设置为 events 资源的 URL
  • Accept 标头设置为 text/event-stream
  • Connection 标头设置为 keep-alive
GET /things/lamp/events HTTP/1.1
Host: mythingserver.com
Accept: text/event-stream
Connection: keep-alive
:使用 JavaScript 打开连接

对于使用 JavaScript [ECMASCRIPT] 实现并在暴露 EventSource 接口的运行时中执行的 消费者, 可以使用 EventSource 构造函数发起服务器发送 事件连接。

const lampEventsSource = new EventSource('/things/lamp/events');

如果 Web Thing 收到符合上述格式的 HTTP 请求,则它 MUST 遵循 服务器发送事件 [EVENTSOURCE] 规范,与 消费者保持打开的连接,并向 消费者推送其有权限 订阅的所有事件类型的事件 数据。

这涉及 Web Thing 首先向 消费者发送具有以下内容的 HTTP 响应:

  • 状态码设置为 200
  • Content-Type 标头设置为 text/event-stream
HTTP/1.1 200 OK
Content-Type: text/event-stream

只要事件在 Web Thing消费者之间存在打开连接期间发生, Web Thing MUST 使用服务器发送事件 [EVENTSOURCE] 规范中的 事件流格式向 消费者 发送事件数据。 对于发送的每条消息,Web Thing MUSTevent 字段设置为 EventAffordance 的名称,并用事件数据(如有)填充 data 字段。 事件数据 MUST 遵循 EventAffordance 中指定的数据 模式,并以 JSON 序列化。 id 字段 SHOULD 设置为事件的唯一标识符,以便在 重新建立断开的连接时使用(见下文)。 RECOMMENDED 该 标识符是一个表示事件发生时间的时间戳(有关日期格式约束,参见 日期格式)。

event: overheated\n
data: 90\n
id: 2021-11-16T16:53:50.817Z\n\n

如果 消费者Web Thing 之间的连接断开(除非是由于下面定义的 unsubscribeallevents 操作所致),消费者 MUST 按照服务器发送事件 规范 [EVENTSOURCE] 中列出的步骤重新建立连接。 连接重新建立后,Web Thing SHOULD 在可能的情况下,发送自 消费者Last-Event-ID 标头中指定的最后一个事件以来发生的任何遗漏 事件。

: 包装在 text/event-stream 中的 application/json

事件载荷以 JSON 序列化,并在 以 text/event-stream 格式序列化的 服务器发送事件的 data 字段中提供。 HTTP 标头中使用的 text/event-stream 内容类型 被假定由 sse 子协议隐含,而嵌入的 application/json 内容类型则在 Form 的 contentType 成员中指明(应用 默认值后)。

7.2.2.4 unsubscribeallevents

为了取消订阅所有事件消费者 MUST 按照服务器发送事件规范 [EVENTSOURCE] 中指定的步骤,终止与 Web Thing 的 events 端点之间的对应 服务器发送事件连接。

: 使用 JavaScript 终止连接

对于使用 JavaScript [ECMASCRIPT] 实现并在暴露 EventSource 接口的运行时中执行的 消费者, 可以使用 EventSource [EVENTSOURCE] 对象上的 close() 方法终止服务器发送 事件连接。

lampEventsSource.close();

8. HTTP Webhook Profile

本节定义 HTTP Webhook Profile,其中包括一个 协议 绑定,用于使用 Webhooks 观察属性并侦听 事件

HTTP Webhook Profile MAYHTTP Basic Profile 结合使用,以便提供读取和写入 属性以及调用、查询和取消动作的操作。

HTTP Webhook Profile MAY 作为 HTTP SSE Profile 的替代事件机制使用。

为了 符合 HTTP Webhook Profile,Web Things消费者 MUST 还必须 符合 通用约束 一节中的所有断言。

:HTTP 客户端 和服务器角色

为了实现 HTTP Webhook Profile, Thing消费者都必须能够同时作为 HTTP 客户端和 HTTP 服务器,并且能够通过 网络相互访问。这在所有部署 场景中可能并不总是可行。

8.1 标识符

为了表示给定的 Web Thing 符合 HTTP Webhook Profile,其 Thing Description MUST 具有一个 profile 成员 [wot-thing-description11], 其值为 https://www.w3.org/2022/wot/profile/http-webhook/v1

请注意,profile 成员是一个数组, 可以包含多个配置文件条目,这 表明某个 Web Thing 符合该数组中 所有的配置文件

8.2 协议绑定

本节定义一个协议绑定,它 描述消费者Web Thing 如何使用 Webhooks 通信。

符合 HTTP Webhook Profile 的消费者Web Thing MUST 实现 此协议绑定。

本节中提供的示例描述了 消费者会如何与产生以下 Thing DescriptionWeb Thing 通信 [wot-thing-description11]:

示例 45: HTTP Webhook Profile 示例 Thing Description
{
  "@context": "https://www.w3.org/2022/wot/td/v1.1",
  "id": "https://mywebthingserver.com/things/lamp",
  "profile": [
    "https://www.w3.org/2022/wot/profile/http-webhook/v1",
  ],
  "base": "https://mywebthingserver.com/things/lamp/",
  "title": "My Lamp",
  "description": "A web connected lamp",
  "securityDefinitions": {
    "oauth2": {
      "scheme": "oauth2",
      "flow": "code",
      "authorization": "https://mywebthingserver.com/oauth/authorize",
      "token": "https://mywebthingserver.com/oauth/token"
    }
  },
  "security": "oauth2",
  "properties": {
    "on": {
      "type": "boolean",
      "title": "On/Off",
      "description": "Whether the lamp is turned on",
      "forms": [
        {
          "op": "observeproperty",
          "href": "properties/on",
          "subprotocol": "webhook",
          "contentType": "application/json",
          "htv:methodName": "POST"
        },
        {
          "op": "unobserveproperty",
          "href": "properties/on/{subscriptionID}",
          "subprotocol": "webhook",
          "htv:methodName": "DELETE"
        }
      ]
    },
    "level" : {
      "type": "integer",
      "title": "Brightness",
      "description": "The level of light from 0-100",
      "unit": "percent",
      "minimum" : 0,
      "maximum" : 100,
      "forms": [
        {
          "op": "observeproperty",
          "href": "properties/level",
          "subprotocol": "webhook",
          "contentType": "application/json",
          "htv:methodName": "POST"
        },
        {
          "op": "unobserveproperty",
          "href": "properties/level/{subscriptionID}",
          "subprotocol": "webhook",
          "htv:methodName": "DELETE"
        }
      ]
    },
  },
  "events": {
    "overheated": {
      "title": "Overheated",
      "data": {
        "type": "number",
        "unit": "degree celsius"
      },
      "description": "The lamp has exceeded its safe operating temperature",
      "subscription": {
        "type": "object",
        "properties": {
          "callbackURL": {
            "type": "string",
            "format": "uri",
            "description": "Callback URL provided by subscriber for Webhook notifications."
          }
        }
      }
      "forms": [
        {
          "op": "subscribeevent",
          "href": "events/overheated",
          "subprotocol": "webhook",
          "contentType": "application/json",
          "htv:methodName": "POST"
        },
        {
          "op": "unsubscribeevent",
          "href": "events/overheated/{subscriptionID}",
          "subprotocol": "webhook",
          "htv:methodName": "DELETE"
        }
      ]
    }
  },
  "forms": [
    {
      "op": "observeallproperties",
      "href": "properties",
      "subprotocol": "webhook",
      "htv:methodName": "POST"
    },
    {
      "op": "unobserveallproperties",
      "href": "properties/{subscriptionID}",
      "suprotocol": "webhook",
      "htv:methodName": "DELETE"
    },
    {
      "op": "subscribeallevents",
      "href": "events",
      "subprotocol": "webhook",
      "htv:methodName": "POST"
    },
    {
      "op": "unsubscribeallevents",
      "href": "events/{subscriptionID}",
      "suprotocol": "webhook",
      "htv:methodName": "DELETE"
    }
  ]
}

8.2.1 属性

8.2.1.1 observeproperty

观察属性值时使用的 property 资源 URL MUST 通过在 Thing Description [wot-thing-description11] 中定位对应 PropertyAffordance 内满足以下条件的 Form 来获得:

  • op 成员包含值 observeproperty
  • 在适用时相对于基 URL 解析后, 其 href 成员值的 URI scheme [RFC3986] 为 httphttps
  • 应用默认值后,其 contentType 成员的值为 application/json
  • subprotocol 成员的值 为 webhook

href 成员解析后的值 随后 MUST 用作 property 资源的 URL。

为了观察属性消费者 MUSTWeb Thing 发送具有以下内容的 HTTP 请求:

  • 方法设置为 POST
  • URL 设置为 property 资源的 URL
  • Content-Type 标头设置为 application/json
  • 主体包含一个 JSON 对象,并具有 以下成员:
    • callbackURL 成员设置为 Thing 应用于向 消费者发送属性变化通知的 回调 URL。
示例 46: 观察属性请求
POST /things/lamp/properties/level HTTP/1.1
Host: mythingserver.com
Content-Type: application/json
{
  callbackURL: "https://myconsumer.com/listeners/d629c54e-a919-463b-8680-602a21f91fe9"
}

如果 Web Thing 收到符合上述格式的 HTTP 请求,并且 消费者有权限 观察对应的属性,则在 成功注册回调 URL 后,它 MUST消费者发送具有以下内容的 HTTP 响应:

  • 状态码设置为 201 Created
  • Location 标头设置为一个唯一 URL, 表示单独的属性观察 订阅,供消费者 之后取消对该 属性的观察时使用。
示例 47: 观察属性响应
HTTP/1.1 201 Created
Location: /things/properties/level/74353483-3997-437a-a4f5-84d03784e517

当属性观察订阅处于 已注册状态时,只要被观察的 属性值发生变化, Web Thing MUST 向进行观察的 消费者发送具有以下内容的 HTTP 请求:

  • 方法设置为 POST
  • URL 设置为 消费者在 注册观察时提供的回调 URL
  • Content-Type 标头设置为 application/json
  • Link 标头,其中 URL 设置为 对应 property 资源的 URL,并且 rel 设置为 self
  • Date 标头由用户代理自动设置为 属性变化的时间,使用 [rfc9110] 中的 HTTP Date 格式
  • 主体包含该属性的新值, 该值以 JSON 序列化,并符合 Property Affordance 的数据模式
示例 48: 属性变化通知请求
POST /listeners/d629c54e-a919-463b-8680-602a21f91fe9 HTTP/1.1
Host: myconsumer.com
Date: Fri, 4 Jul 2025 12:48:00 GMT
Content-type: application/json
Link: <https://mythingserver.com/things/mylamp1/properties/level>; rel="self"
90

消费者在有效的 回调 URL 处收到符合上述格式的 HTTP 请求时,它 MUSTWeb Thing 发送具有以下内容的 HTTP 响应:

  • 状态码设置为 200 OK
示例 49: 属性变化通知响应
HTTP/1.1 200 OK
8.2.1.2 unobserveproperty

为了取消属性的观察订阅, 消费者 MUSTWeb Thing 发送具有以下内容的 HTTP 请求:

  • 方法设置为 DELETE
  • URL 设置为在 observeproperty 操作期间 HTTP 响应的 Location 标头中提供的订阅 URL
示例 50: 取消观察属性请求
DELETE /things/properties/level/74353483-3997-437a-a4f5-84d03784e517 HTTP/1.1 
Host: mythingserver.com

如果 Web Thing 收到符合上述格式的 HTTP 请求, 并且存在使用所提供 URL 的属性观察订阅, 则在成功取消该订阅后, Web Thing MUST消费者发送具有以下内容的 HTTP 响应:

  • 状态码设置为 204 No Content
示例 51: 取消观察属性响应
HTTP/1.1 204 No Content
8.2.1.3 observeallproperties

观察某个 Web Thing 的所有属性值时使用的 properties 资源 URL MUST 通过在 Thing Description [wot-thing-description11] 的顶层 forms 成员中定位满足以下条件的 Thing Description 内的 Form 来获得:

  • op 成员包含值 observeallproperties
  • 在适用时相对于基 URL 解析后, 其 href 成员值的 URI scheme [RFC3986] 为 httphttps
  • 应用默认值后,其 contentType 成员的值为 application/json
  • subprotocol 成员的值 为 webhook

href 成员解析后的值 随后 MUST 用作 properties 资源的 URL。

为了观察某个 Web Thing 的所有属性变化, 消费者 MUSTWeb Thing 发送具有以下内容的 HTTP 请求:

  • 方法设置为 POST
  • URL 设置为 properties 资源的 URL
  • Content-Type 标头设置为 application/json
  • 主体包含一个 JSON 对象,并具有 以下成员:
    • callbackURL 成员设置为 Thing 应用于向 消费者发送属性变化通知的 回调 URL。
示例 52: 观察所有属性请求
POST /things/lamp/properties HTTP/1.1
Host: mythingserver.com
Content-Type: application/json
{
  callbackURL: "https://myconsumer.com/listeners/aa2d8e1f-dc6a-4fe0-a5c0-a42d9f532699"
}

如果 Web Thing 收到符合上述格式的 HTTP 请求,并且 消费者有权限 观察该 Thing属性,则在 成功注册回调 URL 后,它 MUST消费者发送具有以下内容的 HTTP 响应:

  • 状态码设置为 201 Created
  • Location 标头设置为一个唯一 URL, 表示单独的观察 订阅,供消费者 之后取消对所有 属性的观察时使用。
示例 53: 观察所有属性响应
HTTP/1.1 201 Created
Location: /things/properties/a84fc5df-2667-4db2-a767-feb4640f2cf7

当 properties 观察订阅处于 已注册状态时,只要任何可观察 属性的值发生变化, Web Thing MUST 向进行观察的 消费者发送具有以下内容的 HTTP 请求:

  • 方法设置为 POST
  • URL 设置为 消费者在 注册观察订阅时提供的回调 URL
  • Content-Type 标头设置为 application/json
  • Link 标头,其中 URL 设置为 对应 PropertyAffordance 的 URL,并且 rel 设置为 self
  • Date 标头由用户代理自动设置为 属性变化的时间,使用 [rfc9110] 中的 HTTP Date 格式
  • 主体包含该属性的新值, 该值以 JSON 序列化,并符合 PropertyAffordance 的数据模式
示例 54: 属性变化通知请求
POST /listeners/aa2d8e1f-dc6a-4fe0-a5c0-a42d9f532699 HTTP/1.1
Host: myconsumer.com
Date: Fri, 4 Jul 2025 12:56:00 GMT
Content-type: application/json
Link: <https://mythingserver.com/things/mylamp1/properties/level>; rel="self"
86

消费者在有效的 回调 URL 处收到符合上述格式的 HTTP 请求时,它 MUSTWeb Thing 发送具有以下内容的 HTTP 响应:

  • 状态码设置为 200 OK
示例 55: 属性变化通知响应
HTTP/1.1 200 OK
8.2.1.4 unobserveallproperties

为了取消对所有属性的观察, 消费者 MUSTWeb Thing 发送具有以下内容的 HTTP 请求:

  • 方法设置为 DELETE
  • URL 设置为在 observeallproperties 操作期间 HTTP 响应的 Location 标头中提供的订阅 URL
示例 56: 取消观察所有属性请求
DELETE /things/properties/a84fc5df-2667-4db2-a767-feb4640f2cf7 HTTP/1.1 
Host: mythingserver.com

如果 Web Thing 收到符合上述格式的 HTTP 请求, 并且存在使用所提供 URL 的 properties 观察订阅, 则在成功取消该观察订阅后, Web Thing MUST消费者发送具有以下内容的 HTTP 响应:

  • 状态码设置为 204 No Content
示例 57: 取消观察所有属性响应
HTTP/1.1 204 No Content

8.2.2 事件

8.2.2.1 subscribeevent

订阅事件时使用的 event 资源 URL MUST 通过在 Thing Description [wot-thing-description11] 中定位对应 EventAffordance 内满足以下条件的 Form 来获得:

  • op 成员包含值 subscribeevent
  • 在适用时相对于基 URL 解析后, 其 href 成员值的 URI scheme [RFC3986] 为 httphttps
  • 应用默认值后,其 contentType 成员的值为 application/json
  • subprotocol 成员的值 为 webhook

href 成员解析后的值 MUST 随后用作 event 资源的 URL。

为了订阅事件消费者 MUSTWeb Thing 发送具有以下内容的 HTTP 请求:

  • 方法设置为 POST
  • URL 设置为 event 资源的 URL
  • Content-Type 标头设置为 application/json
  • 主体包含一个 JSON 对象,并具有 以下成员:
    • callbackURL 成员设置为 Thing 应用于向 消费者发送事件通知的 回调 URL。
示例 58: 订阅事件请求
POST /things/lamp/events/overheated HTTP/1.1
Host: mythingserver.com
Content-Type: application/json
{
  callbackURL: "https://myconsumer.com/listeners/e79dd0a5-4537-4ded-a10f-bb4eb2aca28d"
}

如果 Web Thing 收到符合上述格式的 HTTP 请求,并且 消费者有权限 订阅对应的事件,则在 成功注册回调 URL 后,它 MUST消费者发送具有以下内容的 HTTP 响应:

  • 状态码设置为 201 Created
  • Location 标头设置为一个唯一 URL, 表示单独的事件订阅,供 消费者之后 取消该订阅时使用。
示例 59: 订阅事件响应
HTTP/1.1 201 Created
Location: /things/events/overheated/ce527faa-a5ab-4f03-8f85-e4411d13edb5

当事件订阅处于已注册状态时, 只要被监视的事件实例发生, Web Thing MUST 向已订阅的 消费者发送具有以下内容的 HTTP 请求:

  • 方法设置为 POST
  • URL 设置为 消费者在 订阅该事件时提供的回调 URL
  • Content-Type 标头设置为 application/json(仅当事件具有 数据载荷时)
  • Link 标头,其中 URL 设置为 对应 event 资源的 URL,并且 rel 设置为 self
  • Date 标头由用户代理自动设置为 事件发生的时间,使用 [rfc9110] 中的 HTTP Date 格式
  • 主体包含事件的数据载荷(如有), 以 JSON 序列化,并符合 EventAffordance 的数据模式

如果事件不包含数据载荷,则请求的 Content-Type 标头 SHOULD NOT 设置,并且主体 should 为空。

有效的 JSON 值——例如 null、空引号 ("")或空花括号({})—— 可能是有效的数据载荷,并不被认为是 “空”主体。

示例 60:事件 通知请求
POST /listeners/e79dd0a5-4537-4ded-a10f-bb4eb2aca28d HTTP/1.1
Host: myconsumer.com
Date: Fri, 4 Jul 2025 16:46:00 GMT
Content-type: application/json
Link: <https://mythingserver.com/things/mylamp1/events/overheated>; rel="self"
90

消费者在有效的 回调 URL 处收到符合上述格式的 HTTP 请求时,它 MUSTWeb Thing 发送具有以下内容的 HTTP 响应:

  • 状态码设置为 200 OK
示例 61:事件 通知响应
HTTP/1.1 200 OK
8.2.2.2 unsubscribeevent

为了取消对事件的订阅, 消费者 MUSTWeb Thing 发送具有以下内容的 HTTP 请求:

  • 方法设置为 DELETE
  • URL 设置为在 subscribeevent 操作期间 HTTP 响应的 Location 标头中提供的订阅 URL
示例 62: 取消订阅事件请求
DELETE /things/events/overheated/ce527faa-a5ab-4f03-8f85-e4411d13edb5 HTTP/1.1 
Host: mythingserver.com

如果 Web Thing 收到符合上述格式的 HTTP 请求, 并且存在使用所提供 URL 的事件订阅, 则在成功取消该订阅后, Web Thing MUST消费者发送具有以下内容的 HTTP 响应:

  • 状态码设置为 204 No Content
示例 63: 取消订阅事件响应
HTTP/1.1 204 No Content
8.2.2.3 subscribeallevents

订阅某个 Web Thing 的所有 事件时使用的 events 资源 URL MUST 通过在 Thing Description [wot-thing-description11] 的顶层 forms 成员中定位满足以下条件的 Thing Description 内的 Form 来获得:

  • op 成员包含值 subscribeallevents
  • 在适用时相对于基 URL 解析后, 其 href 成员值的 URI scheme [RFC3986] 为 httphttps
  • 应用默认值后,其 contentType 成员的值为 application/json
  • subprotocol 成员的值 为 webhook

href 成员解析后的值 随后 MUST 用作 events 资源的 URL。

为了订阅某个 Web Thing 的所有 事件消费者 MUSTWeb Thing 发送具有以下内容的 HTTP 请求:

  • 方法设置为 POST
  • URL 设置为 events 资源的 URL
  • Content-Type 标头设置为 application/json
  • 主体包含一个 JSON 对象,并具有 以下成员:
    • callbackURL 成员设置为 Thing 应用于向 消费者发送事件通知的 回调 URL。
示例 64: 订阅所有事件请求
POST /things/lamp/events HTTP/1.1
Host: mythingserver.com
Content-Type: application/json
{
  callbackURL: "https://myconsumer.com/listeners/bdd2aa13-387b-4c97-9725-52294a9fa5a9"
}

如果 Web Thing 收到符合上述格式的 HTTP 请求,并且 消费者有权限 订阅该 Thing事件,则在 成功注册回调 URL 后,它 MUST消费者发送具有以下内容的 HTTP 响应:

  • 状态码设置为 201 Created
  • Location 标头设置为一个唯一 URL, 表示单独的事件订阅,供 消费者之后 取消该订阅时使用。
示例 65: 订阅所有事件响应
HTTP/1.1 201 Created
Location: /things/events/929dbb69-eb66-46df-a0fe-93701d82e7ea

当 events 订阅处于已注册状态时, 只要事件发生,Web Thing MUST 向 已订阅的消费者发送具有以下内容的 HTTP 请求:

  • 方法设置为 POST
  • URL 设置为 消费者在 注册订阅时提供的回调 URL
  • Content-Type 标头设置为 application/json(仅当事件 包含数据载荷时)
  • Link 标头,其中 URL 设置为 对应 event 资源的 URL,并且 rel 设置为 self
  • Date 标头由用户代理自动设置为 事件发生的时间,使用 [rfc9110] 中的 HTTP Date 格式
  • 主体包含事件数据载荷(如有), 以 JSON 序列化,并符合 EventAffordance 的数据模式

如果事件不包含数据载荷,则请求的 Content-type 标头 SHOULD NOT 设置,并且主体 should 为空。

有效的 JSON 值——例如 null、空引号 ("")或空花括号({})—— 可能是有效的数据载荷,并不被认为是 “空”主体。

示例 66:事件 通知请求
POST /listeners/bdd2aa13-387b-4c97-9725-52294a9fa5a9 HTTP/1.1
Host: myconsumer.com
Date: Fri, 4 Jul 2025 17:04:00 GMT
Content-type: application/json
Link: <https://mythingserver.com/things/mylamp1/events/overheated>; rel="self"
86

消费者在有效的 回调 URL 处收到符合上述格式的 HTTP 请求时,它 MUSTWeb Thing 发送具有以下内容的 HTTP 响应:

  • 状态码设置为 200 OK
示例 67:事件 通知响应
HTTP/1.1 200 OK
8.2.2.4 unsubscribeallevents

为了取消对所有事件的订阅, 消费者 MUSTWeb Thing 发送具有以下内容的 HTTP 请求:

  • 方法设置为 DELETE
  • URL 设置为在 subscribeallevents 操作期间 HTTP 响应的 Location 标头中提供的订阅 URL
示例 68: 取消订阅所有事件请求
DELETE /things/events/929dbb69-eb66-46df-a0fe-93701d82e7ea HTTP/1.1 
Host: mythingserver.com

如果 Web Thing 收到符合上述格式的 HTTP 请求, 并且存在使用所提供 URL 的 events 订阅, 则在成功取消该 events 订阅后, Web Thing MUST消费者发送具有以下内容的 HTTP 响应:

  • 状态码设置为 204 No Content
示例 69: 取消订阅所有事件响应
HTTP/1.1 204 No Content

9. 隐私考虑

WoT Architecture [wot-architecture11] 和 WoT Thing Description [wot-thing-description11] 规范中的隐私考虑 SHOULD 被纳入 考量。

有关实现建议,另请参阅 WoT Security and Privacy Guidelines [wot-security]。

10. 安全考虑

WoT Architecture [wot-architecture11] 和 WoT Thing Description [wot-thing-description11] 规范中的安全考虑 SHOULD 被纳入 考量。

有关实现建议,另请参阅 WoT Security and Privacy Guidelines [wot-security]。

11. 无障碍考虑

Thing Description 各层级 titledescription 成员的值可 用于生成用户界面,因此 SHOULD 是人类可读的 字符串,并且在必要时也可由辅助技术 渲染。

A. 最近的规范变更

A.1 相对于 2023 年 1 月 18 日发布的 WD 的变更

A.2 相对于 2020 年 11 月 24 日发布的 FPWD 的变更

B. 参考文献

B.1 规范性参考文献

[EVENTSOURCE]
服务器发送 事件. Ian Hickson. W3C. 2021 年 1 月 28 日。W3C 推荐标准。URL:https://www.w3.org/TR/eventsource/
[JSON]
JavaScript Object Notation (JSON) 数据交换 格式. T. Bray, Ed. IETF. 2017 年 12 月。 互联网标准。URL:https://www.rfc-editor.org/rfc/rfc8259
[RFC2119]
用于 RFC 中表示要求级别的关键 词. S. Bradner. IETF. 1997 年 3 月。最佳 当前实践。URL:https://www.rfc-editor.org/rfc/rfc2119
[RFC3339]
互联网上的 日期和时间:时间戳. G. Klyne; C. Newman. IETF. 2002 年 7 月。提议标准。URL:https://www.rfc-editor.org/rfc/rfc3339
[RFC3986]
统一 资源标识符(URI):通用语法. T. Berners-Lee; R. Fielding; L. Masinter. IETF. 2005 年 1 月。 互联网标准。URL:https://www.rfc-editor.org/rfc/rfc3986
[RFC7807]
HTTP API 的 问题详情. M. Nottingham; E. Wilde. IETF. 2016 年 3 月。提议标准。URL:https://www.rfc-editor.org/rfc/rfc7807
[RFC8174]
RFC 2119 关键词中 大写与小写的歧义. B. Leiba. IETF. 2017 年 5 月。最佳当前 实践。URL:https://www.rfc-editor.org/rfc/rfc8174
[RFC9110]
HTTP 语义. R. Fielding, Ed.; M. Nottingham, Ed.; J. Reschke, Ed. IETF. 2022 年 6 月。互联网标准。 URL:https://httpwg.org/specs/rfc9110.html
[RFC9112]
HTTP/1.1. R. Fielding, Ed.; M. Nottingham, Ed.; J. Reschke, Ed. IETF. 2022 年 6 月。互联网标准。URL:https://httpwg.org/specs/rfc9112.html
[URL]
URL 标准. Anne van Kesteren. WHATWG. 现行 标准。URL:https://url.spec.whatwg.org/
[wot-architecture11]
Web of Things (WoT) Architecture 1.1. Michael Lagally; Ryuichi Matsukura; Kunihiko Toumura; Michael McCool. W3C. 2023 年 12 月 5 日。W3C 推荐标准。URL: https://www.w3.org/TR/wot-architecture11/
[wot-binding-templates]
Web of Things (WoT) Binding Templates. Michael Koster; Ege Korkan. W3C. 2024 年 5 月 28 日。W3C 工作组 说明。URL:https://www.w3.org/TR/wot-binding-templates/
[wot-discovery]
Web of Things (WoT) Discovery. Kunihiko Toumura; Michael McCool; Andrea Cimmino; Farshid Tavakolizadeh. W3C. 2023 年 12 月 5 日。W3C 推荐标准。URL:https://www.w3.org/TR/wot-discovery/
[wot-thing-description11]
Web of Things (WoT) Thing Description 1.1. Sebastian Käbisch; Michael McCool; Ege Korkan. W3C. 2023 年 12 月 5 日。W3C 推荐标准。URL:https://www.w3.org/TR/wot-thing-description11/
[wot-usecases]
Web of Things (WoT): Use Cases and Requirements. Michael Lagally; Michael McCool; Ryuichi Matsukura; Tomoaki Mizushima. W3C. 2022 年 3 月 7 日。W3C 工作组 说明。URL:https://www.w3.org/TR/wot-usecases/

B.2 资料性参考文献

[ECMASCRIPT]
ECMAScript 语言规范. Ecma International. URL:https://tc39.es/ecma262/multipage/
[H2020-CREATE-IoT]
H2020 - CREATE-IoT Project - 关于 IoT 平台共性和互操作性配置文件的 建议. IoT European Large-Scale Pilots Programme. 2018-11. 已发布。URL: https://european-iot-pilots.eu/wp-content/uploads/2018/11/D06_02_WP06_H2020_CREATE-IoT_Final.pdf
[wot-security]
Web of Things (WoT) Security and Privacy Guidelines. Elena Reshetova; Michael McCool. W3C. 2019 年 11 月 6 日。W3C 工作组说明。URL: https://www.w3.org/TR/wot-security/