我必须使用 HTTP/2.0 发送 Apple 推送通知吗?我可以使用 libcurl 吗?

Posted

技术标签:

【中文标题】我必须使用 HTTP/2.0 发送 Apple 推送通知吗?我可以使用 libcurl 吗?【英文标题】:Must I use HTTP/2.0 to send Apple Push Notifications? May I use libcurl? 【发布时间】:2016-03-30 11:32:04 【问题描述】:

正如你可能从标题中推断的那样,这个问题实际上是两个问题。

第一个问题:我必须使用 HTTP/2.0 发送 Apple 推送通知吗?

在 Apple 提供的APNs Provider API documentation 上,开头的段落指定:

提供者 API 基于 HTTP/2 网络协议。

在整个文档中还有其他几个对 HTTP/2.0 的引用。但是,我没有看到(这并不是说它不存在)任何指定使用 HTTP/2.0 的内容。这是否意味着我可以使用任何 HTTP 版本?还是我实际上受限于 HTTP/2.0?

我对 HTTP/1.1 非常熟悉,但对 HTTP/2.0 几乎一无所知,因此如果我能够使用我熟悉的旧协议,我会更喜欢。

第二个问题(基于第一个问题):我可以将 libcurl 与 APN 一起使用吗?

只有在第一个问题得到肯定回答的情况下,这个问题才有意义。如果不是我必须将 HTTP/2.0 与 APN 一起使用,那么我已经知道我可以使用 libcurl。

我将从一个已经很忙的服务器发送许多 APN,我更愿意在本地进行 - 因此我计划在可能的情况下使用 libcurl。但是我知道 libcurl 在 HTTP/2.0 方面有些限制。

主要问题是当 libcurl 建立一个 HTTP/2.0 连接时,它实际上是从一个包含 upgrade 标头的 HTTP/1.1 请求开始的,然后等待一个 101 Switching Protocols 状态行。 APN 是否支持此行为?还是我必须尝试使用​​nghttp2 之类的东西?

我发现 nghttp2 有点复杂,并且非常目前文档记录很少。我担心如果我不能使用 libcurl,我可能最终不得不使用套接字自己实现 HTTP/2.0(这将是最糟糕的)。

对任何一个问题都表示感谢!谢谢大家!

【问题讨论】:

curl 命令行适用于 HTTP/2 的这种场景。只需使用 --http2 选项和 https:// url 。因此,必须有一种方法可以使 libcurl 也能正常运行...... HTTP/2 在我们不知道它使用哪个版本的普通 HTTP:// URL 上完成,通常使用 Upgrade: HTTPS:// 完成不同。 libcurl 最终也将获得 HTTP2 支持,欢迎您帮助我们实现它。 @DanielStenberg 我真的有兴趣提供帮助。这听起来很有趣。我怎么能参与进来? 不客气!加入 curl-library 邮件列表,说明您想帮助什么,我们会从那里指导您(并讨论解决方案)。还请阅读curl.haxx.se/dev/contribute.html 或者我即将出版的书中的这一章:ec.haxx.se/sourcecode-contributing.html “自 2020 年 11 月起,Apple 推送通知服务 (APN) 将不再支持旧的二进制协议。” developer.apple.com/news/?id=11042019a 【参考方案1】:

2021 年更新 是的,现在需要 HTTP/2 和 JSON 方法,因为二进制协议将于 2021 年 3 月 31 日停止使用。

https://developer.apple.com/news/?id=c88acm2b

为了给您额外的准备时间,升级到 APNs 提供者 API 已延长至 2021 年 3 月 31 日。APNs 将不会 在此日期之后不再支持旧的二进制协议。

【讨论】:

【参考方案2】:

使用 curl 发送 http2 推送消息的示例脚本。假设您拥有来自开发站点的身份验证密钥,并且您的 curl 版本是使用 http2 支持编译的。 p8 file 应该在脚本的同一文件夹中,比如 apns.sh 文件。运行>bash apns.sh

#!/bin/bash

deviceToken=96951ABACECA47F34C2F93D8E58591054E6F2B42691B4EADA6935C19A107A524

authKey="./AuthKey_SLDFJSDLB.p8"
authKeyId=SLDFJSDLB
teamId=ABCDET
bundleId=com.mycompany.myapp
endpoint=https://api.development.push.apple.com
apns_collapse_id="score_update"

read -r -d '' payload <<-'EOF'

   "aps": 
      "badge": 2,
      "category": "mycategory",
      "alert": 
         "title": "my title",
         "subtitle": "my subtitle",
         "body": "my body text message 103"
      
   ,
   "custom": 
      "mykey": "myvalue"
   

EOF

# --------------------------------------------------------------------------

base64() 
   openssl base64 -e -A | tr -- '+/' '-_' | tr -d =


sign() 
   printf "$1"| openssl dgst -binary -sha256 -sign "$authKey" | base64


time=$(date +%s)
header=$(printf ' "alg": "ES256", "kid": "%s" ' "$authKeyId" | base64)
claims=$(printf ' "iss": "%s", "iat": %d ' "$teamId" "$time" | base64)
jwt="$header.$claims.$(sign $header.$claims)"

curl --verbose \
   --header "content-type: application/json" \
   --header "authorization: bearer $jwt" \
   --header "apns-topic: $bundleId" \
   --header "apns-collapse-id: $apns_collapse_id"\
   --http2 \
   --data "$payload" \
   $endpoint/3/device/$deviceToken

【讨论】:

【参考方案3】:

好的,经过很长时间,我终于找到了答案。 是的,需要 HTTP/2 才能使用 APNS

归结为the APNS docs 中的一行

APN 需要使用 HPACK(HTTP/2 的标头压缩),以防止重复的标头键和值。

这意味着 HTTP/2 是协议的必需部分。

【讨论】:

【参考方案4】:

就目前而言,Apple 仍支持其旧版 v2(二进制)API,它通过 HTTPS 运行,因此只有在您想使用最新 API 时才需要 HTTP/2。

遗留 API 记录在附录中,但老实说,与 HTTP/2 API 相比,它太可怕了,我不推荐使用它。

我可以肯定地说,遗留 API 是受支持的,因为我现在有生产代码正在使用它(这也是为什么我可以说 API 很糟糕,我正忙于将它迁移到 HTTP/2)。

【讨论】:

您是否迁移到新的 HTTP/2 API?如果是,那么请让我问一些关于此的问题。我也在做同样的事情 旧系统无法通过 HTTPS 运行。它根本不是 HTTP。它是一种 TLS 加密的二进制协议,不符合任何标准。 二进制 API 将于 2021 年 3 月 31 日停止运行。

以上是关于我必须使用 HTTP/2.0 发送 Apple 推送通知吗?我可以使用 libcurl 吗?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Visual C# 中发送 HTTP 2.0 请求

使用 PHP 向客户端发送多个 HTTP 2.0 流

如何将音频输出发送到 Apple TV?

如何使用 Google Cloud Messaging 将通知推送到 iOS

Apple 的 APNS 交付有时很慢

Apple Wallet - 替换证书并仍然将更新推送到旧卡