golang通过HTTP/2协议发送Apple推送通知插件库APNs2的使用
Golang通过HTTP/2协议发送Apple推送通知插件库APNs2的使用
概述
APNS/2是一个Go语言包,设计用于通过新的HTTP/2推送提供者API在iOS、OSX和Safari上发送简单、灵活且快速的Apple推送通知。
特性
- 使用新的Apple APNs HTTP/2连接
- 快速
- 支持Go 1.7及更高版本
- 支持新的Apple基于令牌的认证(JWT)
- 支持iOS 10新特性如折叠ID、副标题和可变通知
- 支持iOS 15新特性interruptionLevel和relevanceScore
- 支持与APNs的持久连接
- 支持VoIP/PushKit通知(iOS 8及更高版本)
- 模块化且易于使用
- 已在APNs生产环境中测试并运行
安装
- 确保已安装Go并设置了GOPATH
- 安装apns2:
go get -u github.com/sideshow/apns2
如果运行测试套件,还需要安装testify:
go get -u github.com/stretchr/testify
示例代码
基本使用示例
package main
import (
"log"
"fmt"
"github.com/sideshow/apns2"
"github.com/sideshow/apns2/certificate"
)
func main() {
// 加载证书文件
cert, err := certificate.FromP12File("../cert.p12", "")
if err != nil {
log.Fatal("Cert Error:", err)
}
// 创建通知
notification := &apns2.Notification{}
notification.DeviceToken = "11aa01229f15f0f0c52029d8cf8cd0aeaf2365fe4cebc4af26cd6d76b7919ef7"
notification.Topic = "com.sideshow.Apns2"
notification.Payload = []byte(`{"aps":{"alert":"Hello!"}}`) // 参见下面的Payload部分
// 如果要测试直接从XCode运行的构建的推送通知(开发环境),使用:
// client := apns2.NewClient(cert).Development()
// 对于发布到App Store或作为ad-hoc分发的应用,使用Production()
client := apns2.NewClient(cert).Production()
res, err := client.Push(notification)
if err != nil {
log.Fatal("Error:", err)
}
fmt.Printf("%v %v %v\n", res.StatusCode, res.ApnsID, res.Reason)
}
JWT令牌认证示例
authKey, err := token.AuthKeyFromFile("../AuthKey_XXX.p8")
if err != nil {
log.Fatal("token error:", err)
}
token := &token.Token{
AuthKey: authKey,
// 来自开发者账户的KeyID(证书、标识符和配置文件 -> 密钥)
KeyID: "ABC123DEFG",
// 来自开发者账户的TeamID(查看账户 -> 会员资格)
TeamID: "DEF123GHIJ",
}
...
client := apns2.NewTokenClient(token)
res, err := client.Push(notification)
通知结构
通知至少需要DeviceToken、Topic和Payload:
notification := &apns2.Notification{
DeviceToken: "11aa01229f15f0f0c52029d8cf8cd0aeaf2365fe4cebc4af26cd6d76b7919ef7",
Topic: "com.sideshow.Apns2",
Payload: []byte(`{"aps":{"alert":"Hello!"}}`),
}
还可以设置可选的ApnsID、Expiration或Priority:
notification.ApnsID = "40636A2C-C093-493E-936A-2A4333C06DEA"
notification.Expiration = time.Now()
notification.Priority = apns2.PriorityLow
Payload构建
可以使用原始字节作为notification.Payload,也可以使用payload构建器包,它使构建APNs payload变得容易:
// {"aps":{"alert":"hello","badge":1},"key":"val"}
payload := payload.NewPayload().Alert("hello").Badge(1).Custom("key", "val")
notification.Payload = payload
client.Push(notification)
响应和错误处理
APNS/2区分来自Apple的有效响应(指示通知是否发送成功)和不可恢复或意外的错误:
- 如果发生不可恢复的错误(如底层http.Client连接或证书有问题、payload未发送或未收到有效响应),将返回Error
- 如果payload成功发送到Apple并收到文档化的响应,将返回Response
检查通知是否成功发送:
res, err := client.Push(notification)
if err != nil {
log.Println("There was an error", err)
return
}
if res.Sent() {
log.Println("Sent:", res.ApnsID)
} else {
fmt.Printf("Not Sent: %v %v %v\n", res.StatusCode, res.ApnsID, res.Reason)
}
上下文和超时
为了更好地控制请求取消和超时,APNS/2支持上下文:
ctx, cancel = context.WithTimeout(context.Background(), 10 * time.Second)
res, err := client.PushWithContext(ctx, notification)
defer cancel()
速度和性能
为了获得最佳性能,应该保留一个apns2.Client实例,而不是每次推送都重新创建它。底层TLS连接本身可能需要几秒钟来连接和协商,因此如果每次推送都设置和拆除apns2.Client,这将极大地影响性能。(Apple建议始终保持连接打开)
还应该限制apns2.Client实例的数量。底层传输本身有一个http连接池,因此单个客户端实例对大多数用户来说就足够了(一个实例每秒可以处理4000+推送)。如果需要更多,那么每个CPU核心一个实例是一个很好的起点。
命令行工具
APNS/2有一个命令行工具,可以通过go get github.com/sideshow/apns2/apns2
安装。用法:
apns2 --help
usage: apns2 --certificate-path=CERTIFICATE-PATH --topic=TOPIC [<flags>]
Listens to STDIN to send notifications and writes APNS response code and reason to STDOUT.
The expected format is: <DeviceToken> <APNS Payload>
Example: aff0c63d9eaa63ad161bafee732d5bc2c31f66d552054718ff19ce314371e5d0 {"aps": {"alert": "hi"}}
Flags:
--help Show context-sensitive help (also try --help-long and --help-man).
-c, --certificate-path=CERTIFICATE-PATH
Path to certificate file.
-t, --topic=TOPIC The topic of the remote notification, which is typically the bundle ID for your app
-m, --mode="production" APNS server to send notifications to. `production` or `development`. Defaults to `production`
--version Show application version.
许可证
MIT许可证
更多关于golang通过HTTP/2协议发送Apple推送通知插件库APNs2的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
更多关于golang通过HTTP/2协议发送Apple推送通知插件库APNs2的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
使用APNs2库通过HTTP/2协议发送Apple推送通知
APNs2是一个流行的Go语言库,用于通过Apple的HTTP/2推送通知服务(APNs)发送iOS、macOS和Safari推送通知。下面我将详细介绍如何使用这个库。
安装APNs2
首先,你需要安装APNs2库:
go get github.com/sideshow/apns2
基本使用示例
1. 准备必要的证书和密钥
你需要从Apple开发者账户获取以下文件之一:
- 证书文件(.p12)和密码
- 或者认证密钥文件(.p8)
2. 使用证书认证的示例代码
package main
import (
"crypto/tls"
"log"
"github.com/sideshow/apns2"
"github.com/sideshow/apns2/certificate"
"github.com/sideshow/apns2/payload"
)
func main() {
// 1. 加载证书
cert, err := certificate.FromP12File("path/to/cert.p12", "password")
if err != nil {
log.Fatal("证书错误:", err)
}
// 2. 创建客户端
client := apns2.NewClient(cert).Production() // 或者使用 .Development() 测试环境
// 3. 创建通知
notification := &apns2.Notification{
DeviceToken: "设备token字符串",
Topic: "你的应用bundle ID", // 如 com.example.app
Payload: payload.NewPayload().Alert("Hello, APNs2!").Badge(1),
}
// 4. 发送通知
res, err := client.Push(notification)
if err != nil {
log.Fatal("发送错误:", err)
}
log.Printf("状态: %v, 原因: %v", res.StatusCode, res.Reason)
}
3. 使用认证密钥(JWT)的示例代码
package main
import (
"log"
"github.com/sideshow/apns2"
"github.com/sideshow/apns2/token"
"github.com/sideshow/apns2/payload"
)
func main() {
// 1. 创建认证令牌
authKey, err := token.AuthKeyFromFile("path/to/AuthKey_XXX.p8")
if err != nil {
log.Fatal("令牌错误:", err)
}
token := &token.Token{
AuthKey: authKey,
KeyID: "你的密钥ID", // 从Apple开发者账户获取
TeamID: "你的团队ID", // 从Apple开发者账户获取
}
// 2. 创建客户端
client := apns2.NewTokenClient(token).Production() // 或者使用 .Development() 测试环境
// 3. 创建通知
notification := &apns2.Notification{
DeviceToken: "设备token字符串",
Topic: "你的应用bundle ID",
Payload: payload.NewPayload().Alert("Hello from JWT!").Sound("default"),
}
// 4. 发送通知
res, err := client.Push(notification)
if err != nil {
log.Fatal("发送错误:", err)
}
log.Printf("状态: %v, 原因: %v", res.StatusCode, res.Reason)
}
高级功能
自定义HTTP/2客户端
cert, err := certificate.FromP12File("path/to/cert.p12", "password")
if err != nil {
log.Fatal("证书错误:", err)
}
// 自定义TLS配置
tlsConfig := &tls.Config{
Certificates: []tls.Certificate{cert},
MinVersion: tls.VersionTLS12, // HTTP/2需要TLS 1.2或更高
}
// 创建自定义HTTP客户端
httpClient := &http.Client{
Transport: &http.Transport{
TLSClientConfig: tlsConfig,
},
}
// 使用自定义HTTP客户端
client := apns2.NewClientWithHTTPClient(httpClient).Production()
发送静默通知
notification := &apns2.Notification{
DeviceToken: "设备token",
Topic: "com.example.app",
Payload: payload.NewPayload().ContentAvailable(),
}
发送自定义数据
notification := &apns2.Notification{
DeviceToken: "设备token",
Topic: "com.example.app",
Payload: payload.NewPayload().
Alert("新消息").
Custom("custom_key", "custom_value").
Custom("another_key", map[string]interface{}{"nested": "value"}),
}
错误处理
APNs2会返回详细的错误信息:
res, err := client.Push(notification)
if err != nil {
if res != nil {
log.Printf("APNs错误: %v, 原因: %v", res.StatusCode, res.Reason)
} else {
log.Printf("网络错误: %v", err)
}
return
}
性能优化
对于高吞吐量场景,可以复用客户端:
// 初始化时创建客户端
var client *apns2.Client
func init() {
cert, _ := certificate.FromP12File("cert.p12", "password")
client = apns2.NewClient(cert).Production()
}
// 然后可以多次调用
func sendNotification(token string, message string) {
notification := &apns2.Notification{
DeviceToken: token,
Topic: "com.example.app",
Payload: payload.NewPayload().Alert(message),
}
client.Push(notification)
}
总结
APNs2库提供了简单而强大的接口来通过HTTP/2协议与Apple推送通知服务交互。它支持两种认证方式(证书和JWT),提供了丰富的通知定制选项,并且可以轻松处理错误和性能优化。