[翻译]Go语言开发苹果推送通知

mikespook · · 3650 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

原文在此:http://bravenewmethod.wordpress.com/2011/02/25/apple-push-notifications-with-go-language/

前两天正巧看到 APNS 没有 Go 的实现,还在琢磨怎么实现一个试试,这下我又省心了。文章本身并不怎么出色,代码倒是有些用途。翻译这篇东西纯粹是为了给自己后面的工作留个资料。大家有用则用,无用就无视吧。

————–翻译分割线————–

Go语言开发苹果推送通知

我开始尝试学习并熟悉 Go 语言,并且做了一些普通的常识,例如,发送苹果推送通知(Apple Push Notifications)。这是我个人对一些开发环境的性能测试。迄今为止,已经有:

第一步 准备

获取并编译 Go。这里的例子是在 Ubuntu 10.04 LTS x64 上,基于 Go 上手指南(Go getting started guide) 里的介绍进行安装。

  • 关于苹果推送和取得应用沙盒私钥的 .pem 文件的介绍在这里
  • 当然,你必须从 iOS 应用获取 32 位的推送令牌(push token)。

第二部 代码

这里是完整的代码,复制并保存为文件 apn.go。

注意修改证书文件(cert.pem 和 key-noenc.pem)为你自己的证书文件。同时,替换推送令牌为你自己的推送令牌, 在这个例子里为了更加清楚,使用十六进制字符串书写。

package main

import (
   "crypto/tls"
   "fmt"
   "net"
   "json"
   "os"
   "time"
   "bytes"
   "encoding/hex"
   "encoding/binary"
)

func main() {

   // 加载证书和配置文件
   cert, err := tls.LoadX509KeyPair("cert.pem", "key-noenc.pem")
   if err != nil {
       fmt.Printf("error: %s\n", err.String())
       os.Exit(1)
   }
   conf := &tls.Config {
        Certificates: []tls.Certificate{cert},
   }

   // 连接到 APNS 并且用 tls 客户端加密 socket
   conn, err := net.Dial("tcp", "", "gateway.sandbox.push.apple.com:2195")
   if err != nil {
      fmt.Printf("tcp error: %s\n", err.String())
      os.Exit(1)
   }
   tlsconn := tls.Client(conn, conf)

   // 强制握手,以验证身份握手被处理,否则会在第一次读写的时候进行尝试
   err = tlsconn.Handshake()
   if err != nil {
      fmt.Printf("tls error: %s\n", err.String())
      os.Exit(1)
   }
   // 调试信息
   state := tlsconn.ConnectionState()
   fmt.Printf("conn state %v\n", state)

   // 从 JSON 结构构造二进制的 payload
   payload := make(map[string]interface{})
   payload["aps"] = map[string]string{"alert": "Hello Push"}
   bpayload, err := json.Marshal(payload)

   // 将十六进制的设备令牌转为二进制的字节数组
   btoken, _ := hex.DecodeString("6b4628de9317c80edd1c791640b58fdfc46d21d0d2d1351687239c44d8e30ab1")

   // 构造 pdu
   buffer := bytes.NewBuffer([]byte{})
   // 命令
   binary.Write(buffer, binary.BigEndian, uint8(1))

   // 传输 id,optional
   binary.Write(buffer, binary.BigEndian, uint32(1))

   // 过期时间,1小时
   binary.Write(buffer, binary.BigEndian, uint32(time.Seconds() + 60*60))

   // 推送设备令牌
   binary.Write(buffer, binary.BigEndian, uint16(len(btoken)))
   binary.Write(buffer, binary.BigEndian, btoken)

   // 推送 payload
   binary.Write(buffer, binary.BigEndian, uint16(len(bpayload)))
   binary.Write(buffer, binary.BigEndian, bpayload)
   pdu := buffer.Bytes()

   // 写入 pdu
   _, err = tlsconn.Write(pdu)
   if err != nil {
      fmt.Printf("write error: %s\n", err.String())
      os.Exit(1)
   }

   // 等待 5 秒,以便 pdu 从 socket 返回错误
   tlsconn.SetReadTimeout(5*1E9)

   readb := [6]byte{}
   n, err := tlsconn.Read(readb[:])
   if n > 0 {
     fmt.Printf("received: %s\n", hex.EncodeToString(readb[:n]))
   }

   tlsconn.Close()
}

第三步 编译和运行

简单

$ 6g apn.go
$ 6l apn.6
$ ./6.out
conn state {true 47}
$

如果所有都没有问题,程序会在几秒钟后退出,你会在你的 iPhone 上看到推送通知。


有疑问加站长微信联系(非本文作者)

本文来自:mikespook 的博客

感谢作者:mikespook

查看原文:[翻译]Go语言开发苹果推送通知

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:701969077

3650 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传