5. 请求推送消息投递
5. 请求推送消息投递
应用服务器 (application server) 通过向用户代理分发给它的推送资源发送 HTTP POST 请求来请求投递推送消息. 推送消息的内容包含在请求体中.
POST /push/JzLQ3raZJfFBR0aqvOMsLrt54w4rJUsV HTTP/1.1
Host: push.example.net
TTL: 15
Content-Type: text/plain;charset=utf8
Content-Length: 36
iChYuI3jMzt3ir20P8r_jgRR-dSuN182x7iB
201 (Created) 响应表示推送消息已被接受. 必须在 Location 头字段中返回因该请求而创建的推送消息资源的 URI. 这不表示消息已投递给用户代理 (user agent).
HTTP/1.1 201 Created
Date: Thu, 11 Dec 2014 23:56:55 GMT
Location: https://push.example.net/message/qDIYHNcfAIPP_5ITvURr-d6BGt
5.1. Requesting Push Message Receipts (请求推送消息回执)
应用服务器可在 Prefer 头字段 [RFC7240] 中包含 respond-async 偏好, 以在推送消息被投递并由用户代理确认后请求推送服务的确认. 推送服务必须 (MUST) 支持投递确认.
POST /push/JzLQ3raZJfFBR0aqvOMsLrt54w4rJUsV HTTP/1.1
Host: push.example.net
Prefer: respond-async
TTL: 15
Content-Type: text/plain;charset=utf8
Content-Length: 36
iChYuI3jMzt3ir20P8r_jgRR-dSuN182x7iB
当推送服务接受带确认投递的消息时, 必须 (MUST) 返回 202 (Accepted) 响应. 必须在 Location 头字段中返回因该请求而创建的推送消息资源的 URI. 推送服务还必须 (MUST) 在类型为 urn:ietf:params:push:receipt 的链接关系中提供回执订阅资源的 URI.
HTTP/1.1 202 Accepted
Date: Thu, 11 Dec 2014 23:56:55 GMT
Link: </receipt-subscription/3ZtI4YVNBnUUZhuoChl6omUvG4ZM>;
rel="urn:ietf:params:push:receipt"
Location: https://push.example.net/message/qDIYHNcfAIPP_5ITvURr-d6BGt
对同一源 [RFC6454] 的后续回执请求, 应用服务器应当 (SHOULD) 在类型为 urn:ietf:params:push:receipt 的链接关系中包含返回的回执订阅. 这使推送服务可以选择聚合回执. 推送服务应当 (SHOULD) 在响应中返回相同回执订阅, 尽管若无法复用应用服务器提供的订阅, 也可以 (MAY) 返回新回执订阅.
若无法在回执订阅生存期内以聚合方式接收回执, 应用服务器可以 (MAY) 省略回执订阅. 若应用服务器代表其他推送消息发送方监视回执订阅, 则可能有此必要.
推送服务必须 (MUST) 对包含无效回执订阅的请求返回 400 (Bad Request) 状态码. 若推送服务希望限制其维护的回执订阅数量, 可以 (MAY) 返回 429 (Too Many Requests) 状态码 [RFC6585] 以拒绝省略回执订阅的回执请求.
5.2. Push Message Time-To-Live (推送消息生存时间)
推送服务通过在一段时间内存储推送消息可显著提升投递可靠性. 用户代理往往仅间歇性连接, 因此受益于推送服务端的短期消息存储.
延迟投递也可用于与用户代理批量通信, 从而节省无线电资源.
某些推送消息在超过特定时间后便不再有用. 在消息已失去相关性之后仍进行投递是浪费. 例如, 若推送消息包含来电通知, 在主叫方已放弃呼叫后收到消息毫无价值, 用户代理上的应用不得不抑制该消息以免产生无用提醒.
应用服务器必须 (MUST) 在投递推送消息的请求中包含 TTL (Time-To-Live, 生存时间) 头字段. TTL 头字段包含以秒为单位的值, 建议推送服务保留推送消息的时长.
TTL 规则指定非负整数, 表示以秒为单位的时间. 接收方解析并将 TTL 值转换为二进制形式时应当 (SHOULD) 使用至少 31 位非负整数范围的算术类型. 若接收方收到的 TTL 值大于其能表示的最大整数, 或其后续任何计算溢出, 则必须 (MUST) 将该值视为 2147483648 (2^31).
TTL = 1*DIGIT
推送服务必须 (MUST) 对省略 TTL 头字段的请求返回 400 (Bad Request) 状态码.
推送服务可以 (MAY) 将推送消息保留比请求更短的时间. 它通过在响应中返回带有实际 TTL 的 TTL 头字段来表明这一点. 该 TTL 值必须 (MUST) 小于或等于应用服务器提供的值.
一旦 TTL 期限届满, 推送服务禁止 (MUST NOT) 再尝试将推送消息投递给用户代理. 推送服务可能调整 TTL 值以补偿处理中的时间计量误差. 例如, 在服务器集群内分发推送消息可能因时钟偏差或传播延迟而累积误差.
推送服务无义务计入应用服务器向推送服务发送推送消息所花费的时间, 或向用户代理发送推送消息时产生的延迟. 应用服务器在选择 TTL 头字段值时需要考虑传输延迟.
TTL 为零的推送消息若用户代理可接收则立即投递. 投递后, 允许推送服务立即删除 TTL 为零的推送消息. 这可能发生在用户代理通过对推送消息资源执行 HTTP DELETE 确认收到消息之前. 因此, 应用服务器不能依赖收到 TTL 为零的推送消息的确认回执.
若用户代理不可用, TTL 为零的推送消息将过期且永不投递.
5.3. Push Message Urgency (推送消息紧急程度)
对电池供电设备而言, 长时间保持休眠往往至关重要. 尤其是无线电通信消耗大量电力并限制设备可运行时间.
为避免为接收琐碎消息而消耗资源, 若应用服务器能传达消息的紧急程度且用户代理能请求推送服务器仅转发特定紧急程度的消息, 将很有帮助.
应用服务器可以 (MAY) 在投递推送消息的请求中包含 Urgency 头字段. 该头字段表示消息紧急程度. 推送服务禁止 (MUST NOT) 将 Urgency 头字段转发给用户代理. 不带 Urgency 头字段的推送消息默认为 normal.
用户代理在监视推送消息时可以 (MAY) 包含 Urgency 头字段, 以表示其愿意接收的最低推送消息紧急程度. 推送服务禁止 (MUST NOT) 投递紧急程度低于用户代理在其监视请求中所示值的推送消息. 监视消息时未包含 Urgency 头字段的用户代理将接收任意紧急程度的推送消息.
Urgency 头字段的语法如下:
Urgency = urgency-option
urgency-option = ("very-low" / "low" / "normal" / "high")
按紧急程度递增:
| Urgency | Device State (设备状态) | Example Application Scenario (示例应用场景) |
|---|---|---|
| very-low | On power and Wi-Fi | Advertisements (广告) |
| low | On either power or Wi-Fi | Topic updates (主题更新) |
| normal | On neither power nor Wi-Fi | Chat or Calendar Message (聊天或日历消息) |
| high | Low battery | Incoming phone call or time-sensitive alert (来电或时效性提醒) |
表 1: 说明性紧急程度取值
请求中禁止 (MUST NOT) 包含 Urgency 头字段的多个值, 否则推送服务必须 (MUST) 返回 400 (Bad Request) 状态码.
5.4. Replacing Push Messages (替换推送消息)
已被推送服务存储的推送消息可用新内容替换. 若发送推送消息期间用户代理离线, 更新推送消息可避免向用户代理发送过时或冗余消息.
仅已分配主题 (topic) 的推送消息可被替换. 带主题的推送消息会替换任何具有相同主题的未决推送消息.
推送消息主题是携带在 Topic 头字段中的字符串. 主题用于关联发往同一订阅的推送消息, 不传达其他语义.
Topic 头字段的语法使用 [RFC7230] 中定义的 token 规则.
Topic = token
在本协议中使用时, Topic 头字段必须 (MUST) 限制为不超过 32 个字符, 且字符来自 URL 与文件名安全的 Base 64 字母表 [RFC4648]. 若推送服务收到的请求中 Topic 头字段不满足这些约束, 必须 (MUST) 向应用服务器返回 400 (Bad Request) 状态码.
推送消息替换请求会创建新的推送消息资源, 并同时删除具有匹配主题的任何现有消息资源. 若曾尝试投递被删除的推送消息, 在推送消息被替换之后确认仍可能到达推送服务. 对此类已删除消息的投递回执应当 (SHOULD) 被抑制.
替换请求还会替换所存储的 TTL、Urgency 以及与匹配主题上前一条消息关联的任何回执订阅.
主题未被发往同一订阅的未决消息共享的推送消息按常规存储或投递.
例如, 下列消息可能导致现有消息被替换:
POST /push/JzLQ3raZJfFBR0aqvOMsLrt54w4rJUsV HTTP/1.1
Host: push.example.net
TTL: 600
Topic: upd
Content-Type: text/plain;charset=utf8
Content-Length: 36
ZuHSZPKa2b1jtOKLGpWrcrn8cNqt0iVQyroF
若推送服务识别到主题为 upd 的未决推送消息, 则删除该消息资源. 201 (Created) 响应表示推送消息替换已被接受. Location 头字段中包含因该请求而创建的新推送消息资源的 URI.
HTTP/1.1 201 Created
Date: Thu, 11 Dec 2014 23:57:02 GMT
Location: https://push.example.net/message/qDIYHNcfAIPP_5ITvURr-d6BGt
Topic 头字段的值禁止 (MUST NOT) 转发给用户代理. 其值既不加密也不认证.