apns

package module
v0.0.0-...-826d3ec Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 20, 2015 License: MIT Imports: 14 Imported by: 0

README

Build Status

Golang APNs package#

###Apple Push notification package###

This package is made with the ideea to be able to send a lot of messages to Apple APNs very very fast atomaticaly scaling with your sending needs

###Package features###

  • multiple managed connections to Aple APNs
  • non blocking waiting for message confirmation
  • try's to ensure the delivery of the message and to give little false positive errors
  • push service reporting running each 5 min on info level (each counter is reset after print) APNs Report - ActivePool: (current size of the active services), PoolSize: (the current pool size), Queue: (instant queue size), Sent: (total sent), ReSent: (total resent), Confirmed: (success confirmed messages),ConfirmedFailed: (total failed confirmed), ConfirmTimeAvg: (confirm duration avg) SendingTime: (sending enter in push notification until exit avg time)

###How this package works###

  • when you post a new message this is going posted to a queue
  • the message is going to be take by a managed connection and sent to Apple
  • after this the message will be moved to a sent queue where he is waiting his status as the status is explained after
  • each message will be added to the confirmed queue, where you will receive the status of the message
  • make sure you consume the messages from confirmation queue because this can block sending

######A message status will be set like this######

  • if a messages was sent more then "SuccessTimeout" ago - OK
  • if status 0 (this i think isn't going to happen as apple says) - OK
  • if status 1 it's a proccessing error, we retry - FAIL (Temporary, Reconnect)
  • if status 2 to 8 it's device token or payload error - FAIL (Permanent)
  • if status 10 the payload was sent - OK (Reconnect)
  • if status 255 it's unknown error - FAIL (Temporary, Reconnect)
  • if status number unknown - FAIL (Temporary, Reconnect)
  • if read/write socket channel closed - FAIL (Permanent, Reconnect)
    • we make it as permanent on connection close because we don't know the status and this can close all the connections from the pool

######Notes:######

  • Permanent - means that the error it's because of the payload/device token so will not be retried
  • Temporary - means that will fail only after "MaxMessageRetry", until this it will be requeued
  • Reconnect - means that the socket used for that message will be closed and a new one will be created
    • reconnect has a protection not to connect faster then "ReconnectDistanceTime" seconds
    • all that are not confirmed in the queue will be mark as failed and temporary error

###Example###

certificate/certificateKey can be path to file or the inline certificate

Configuration:

    SuccessTimeout        time.Duration //default 500ms
	MaxMessageRetry       uint 			//default 5
    MessageQueueSize      uint          //default 1000
    
    NotficationPriority    uint8         //default 10 (will downgrade to 5 if no sound/alert/badge set)
    NotificationExpiration time.Duration //default 24h because this is can be 0 you must set a value to field or to use the default one set -1 

	IsProduction bool //default false

	Certificate    string //no default value
	CertificateKey string //no default value

	MinPoolSize uint                    //default 1
	MaxPoolSize uint                    //default 2
	UpgradePool uint                    //default 200
	DowngradePool uint                  //default 50 (max val for downgrade is 1/2 from upgrade)
	ReconnectDistanceTime time.Duration //default 10s
	//Connection pool will upgrade if there are more then UpgradePool messages in the queue to be sent new connection it will be added each 10 seconds until the queue will be < UpgradePool or MaxPoolSize will be reachedThe downgrade will remove a connection if 300 seconds the queue will be < DowngradePool or the MinPoolSize will be reached (we wait 300 so apple will not consider us as dos attack)

    ReportingInterval time.Duration //default 5min - the interval between to reports

    FeedbackReadTimeout time.Duration //default 20s - how long to wait for messages on a connection

init returns error if certificates not set or they are wrong, you can call multiple time, only if err != nil, will panic if you try to init after a success

cfg := &apns.Config{
    MaxPoolSize: 10,
    SuccessTimeout: time.Miliseccond * 300,
    NotificationExpiration: time.Duration(-1),
} //this config will overwrite the default ones
if err:= apns.Init(cfg); err != nil {
	  //do something
}
//see more on payload or you can use any object that conforms to PayloadInterface
payload := apns.NewPayload()
payload.Alert = "APNs Testing"

pushNotification := apns.NewPushNotification()
//device token is hex string (string len 64)
pushNotification.DeviceToken = "980f7123456788f1cf31a3fc1eb4d3ec8054b36b4ed158f2c65784925fc0000"
pushNotification.AddPayload(payload)

apns.Send(pushNotification)
pushNotificationStatus := <-apns.Confirmation()

###Feedback Service###

  • we can consume the messages by channel err:= apns.Feedback()

  • feedback service and is returning an object with 3 methods Channel, Interval and Stop, on Channel you will recevie all the feedback messages

  • Interval check at each interval for new messages

  • Interval is default 0, this will make it do only one request then will stop, if interval > 0 then at each interval will check for new message (the timer is started when you request the channel)

  • after Stop make sure you read until channel close so you get all the messages

###Logging:###

  • you can use 2 type's of loggers
apns.SetGoLogger(logger)// if you use go standard logger
apns.SetLogger(logger) //for this you need a logger with Debug/Info/Warning/Error methods as interface apns.Logger
Docs

#####Note:##### this library conforms with apple specifications

###TO DO:###

  • unit tests
  • time between message resends
  • improve feedback service
  • examples

Documentation

Index

Constants

View Source
const (
	SANDBOX_GATEWAY    = "gateway.sandbox.push.apple.com:2195"
	PRODUCTION_GATEWAY = "gateway.push.apple.com:2195"

	SANDBOX_FEEDBACK_GATEWAY    = "feedback.push.apple.com:2196"
	PRODUCTION_FEEDBACK_GATEWAY = "feedback.sandbox.push.apple.com:2196"
)
View Source
const (
	MaxNotificationSizeBytes = 2048 //max notification data size (2K)
)

Variables

This section is empty.

Functions

func Confirm

func Confirm() <-chan *ApnsMessage

you will receive the message sent status on this channel on error the SetError will be called on the payload and with that you can check the why and if it has failed you must read the confirm or after MessageQueueSize messages will block start blocking the error will be the last error from the retry confirm is safe to be called from multiple go rutines

func Feedback

func Feedback() *feedback

this method will start the feedback service and is returning an object with 3 methods Channel, Interval and Stop on Channel you will recevie all the feedback messages Interval check at each interval for new messages Interval is default 0, this will make it do only one request then will stop, if interval > 0 then at each interval will check for new message (the timer is started when you request the channel) after Stop make sure you read until channel close so you get all the messages

func Init

func Init(cfg Config) error

func NewAlertDictionary

func NewAlertDictionary() *alertDictionary

func NewNotification

func NewNotification() *notification

func Send

func Send(payload PayloadInterface, deviceToken string) (messageIdentification uint32)

send a apns message, 0 and max uint32 id's are reserved, don't use them the status of the payload must be read from Confirmation channel you must read the confirm or after MessageQueueSize messages will block start blocking sent is safe to be called from multiple go rutines

func SetGoLogger

func SetGoLogger(logger *log.Logger)

func SetLogger

func SetLogger(logger Logger)

Types

type ApnsMessage

type ApnsMessage struct {
	PayloadInterface

	DeviceToken string
	Error       error
	// contains filtered or unexported fields
}

func (*ApnsMessage) SetStatus

func (a *ApnsMessage) SetStatus(err error, permanentError bool)

type Config

type Config struct {
	SuccessTimeout   time.Duration //the duration after that a message without response will be considered success
	MaxMessageRetry  uint          //max times to retry and send a message before we reported as failed
	MessageQueueSize uint          //max number of messages that are going to be in the send/confirm and feedback channel
	//note that the channel will block if is going to be full
	NotificationPriority   uint8         // the default priority is 10 (if alert/sound/badge not set, will be forced to 5)
	NotificationExpiration time.Duration // the default duration after wich apple will expire the notif

	IsProduction bool //should i use production or sandbox enviroment ?

	Certificate    string //inline certificate or file path (note certificate and the key must be the same file or inline)
	CertificateKey string //inline certificate key or file path

	ReconnectDistanceTime time.Duration //the min distance to reconnect a failed connection
	MinPoolSize           uint          //min connection pool size
	MaxPoolSize           uint          //max connection pool size
	UpgradePool           uint          //the number of messages in the queue (for 10s) after wich the pool will be upgraded
	DowngradePool         uint          //the number of messages in the queue (for 5 min) after wich the poll will be downgraded

	ReportingInterval time.Duration //the interval between to reports

	FeedbackReadTimeout time.Duration //how long to wait for messages on a connection
	// contains filtered or unexported fields
}

type FeedbackMessage

type FeedbackMessage struct {
	DeviceToken  string
	DiscoverTime time.Time
}

type Logger

type Logger interface {
	Debug(format string, args ...interface{})
	Info(format string, args ...interface{})
	Warning(format string, args ...interface{})
	Error(format string, args ...interface{})
}

type PayloadInterface

type PayloadInterface interface {
	ToJson() ([]byte, error)
	Config() (expiration uint32, priority uint8)
}

type PushNotification

type PushNotification struct {
	// contains filtered or unexported fields
}

func NewPushNotification

func NewPushNotification() *PushNotification

func (*PushNotification) Config

func (pn *PushNotification) Config() (expiration uint32, priority uint8)

func (*PushNotification) SetCustom

func (pn *PushNotification) SetCustom(key string, value interface{})

func (*PushNotification) SetExpire

func (pn *PushNotification) SetExpire(expire time.Duration)

func (*PushNotification) SetNotification

func (pn *PushNotification) SetNotification(n *notification)

func (*PushNotification) SetPriority

func (pn *PushNotification) SetPriority(priority uint8)

func (*PushNotification) ToJson

func (pn *PushNotification) ToJson() (data []byte, err error)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL