Skip to content

Instantly share code, notes, and snippets.

@joekarl
Last active May 23, 2016 13:41
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save joekarl/86d9bdb8f9af044710b7 to your computer and use it in GitHub Desktop.
Save joekarl/86d9bdb8f9af044710b7 to your computer and use it in GitHub Desktop.
go-libapns example app
package main
import (
apns "github.com/joekarl/go-libapns"
"fmt"
"io/ioutil"
"time"
)
type HandleCloseErrorFn func (closeError *apns.ConnectionClose)
func main() {
certPem, err := ioutil.ReadFile("../certs/PushTestCert.pem")
if err != nil {
panic(err)
}
keyPem, err := ioutil.ReadFile("../certs/PushTestKey-noenc.pem")
if err != nil {
panic(err)
}
config := &apns.APNSConfig{
CertificateBytes: certPem,
KeyBytes: keyPem,
GatewayHost: "gateway.sandbox.push.apple.com",
}
shutdownChannel := make(chan bool)
sendChannel := make(chan *apns.Payload)
doneWritingChan := make(chan bool)
go poster(sendChannel, doneWritingChan)
go apnsService(config, sendChannel, handleCloseError, shutdownChannel)
// wait till we're done writing
<-doneWritingChan
shutdownChannel <- true
// wait for things to shutdown
fmt.Println("waiting to shutdown")
<-shutdownChannel
}
func poster(sendChannel chan<- *apns.Payload, doneWritingChan chan bool) {
for i := 0; i < 10000; i++ {
payload := &apns.Payload {
Token: "8b3c461df225ac9e4a2b7d6bd6b4cec093ad734f7bf681a56cf59d5748f40e3a",
AlertText: fmt.Sprintf("This is a push notification %v!", i),
ExtraData: i,
}
sendChannel <- payload
}
doneWritingChan <- true
}
func apnsService(config *apns.APNSConfig, sendChannel <-chan *apns.Payload, closeErrFn HandleCloseErrorFn, shutdownChannel chan bool) {
shutdown := false
connectionGood := false
var lastConn *apns.APNSConnection = nil
for {
if shutdown {
break
}
fmt.Println("establishing connection")
conn, err := apns.NewAPNSConnection(config)
if err != nil {
connectionGood = false
fmt.Println(err)
select {
case <-time.After(time.Second * 5):
continue
case <-shutdownChannel:
shutdown = true
}
} else {
lastConn = conn
connectionGood = true
}
for {
if !connectionGood || shutdown {
break
}
select {
case payload := <- sendChannel:
fmt.Printf("sending id %v\n", payload.ExtraData)
select {
case <-time.After(time.Second * 1):
break
case conn.SendChannel <- payload:
break
}
break
case closeError := <-conn.CloseChannel:
closeErrFn(closeError)
connectionGood = false
fmt.Println("Received error, closing connection")
break
case <-shutdownChannel:
fmt.Println("Received shutdown signal, closing connection")
conn.Disconnect()
shutdown = true
}
}
fmt.Println("Connection killed attempting re-establish")
}
if lastConn != nil {
select {
case <-time.After(time.Second * 5):
break
case closeError := <-lastConn.CloseChannel:
closeErrFn(closeError)
}
}
fmt.Println("going to shutdown")
shutdownChannel <- true
}
func handleCloseError(closeError *apns.ConnectionClose) {
// do something here with unsent payloads
fmt.Println(closeError.Error)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment