Documentation ¶
Overview ¶
Package apns provides a client for Apple Push Notification Service (APNS) and corresponding feedback service.
Index ¶
- Constants
- Variables
- type BadMessageCallback
- type BadToken
- type Client
- func (c *Client) Send(to string, expiry time.Time, priority uint8, payload map[string]interface{}) error
- func (c *Client) SetCallback(cb BadMessageCallback)
- func (c *Client) SetupFeedback(gw string, poll time.Duration) (*FeedbackClient, error)
- func (c *Client) Start(workerCount int) error
- func (c *Client) Stop() error
- type FeedbackClient
- type Message
Constants ¶
const ( // How many times try to connect to APNS (prevents denial on dns failures). WORKER_RETRIES = 3 // Waits specified amount of time for next connection attempt. WORKER_RESSURECT_TIMEOUT = 15 * time.Second // Message queue length. CLIENT_QUEUE_LENGTH = 32 // Worker respawn queue length. RESPAWN_QUEUE_LENGTH = 4 // Default port for APNS. APNS_DEFAULT_PORT = 2195 // Default port for feedback service. FEEDBACK_DEFAULT_PORT = 2196 )
const ( // Tell APNS to deliver message without delay. PRIORITY_IMMEDIATE = 10 // Tell APNS to deliver message in background. PRIORITY_DELAYED = 5 )
const ( FRAME_TOKEN_LENGTH uint16 = 32 FRAME_NOTIFICATION_ID_LENGTH uint16 = 4 FRAME_EXPIRATION_DATE_LENGTH uint16 = 4 FRAME_PRIORITY_LENGTH uint16 = 1 FRAME_TOKEN_ID uint8 = 1 FRAME_PAYLOAD_ID uint8 = 2 FRAME_NOTIFICATION_ID_ID uint8 = 3 FRAME_EXPIRATION_DATE_ID uint8 = 4 FRAME_PRIORITY_ID uint8 = 5 FRAME_PROTO_VERSION uint8 = 2 )
There are constants for APNS protocol frames.
const ( // Timeout for messages to be 'assumed delivered' to APNS. After message being written into // APNS connection, worker will put it into inflight queue. If no errors was recieved from APNS // during that amount of time, message assumed delivered to APNS. WORKER_ASSUME_SENT_TIMEOUT = time.Second * 5 // Initial buffer size for inflight messages. WORKER_INFLIGHT_QUEUE_SIZE = 128 // Period to check inflight queue. WORKER_QUEUE_UPDATE_FREQ = time.Millisecond * 500 // Long-living connections to APNS tend to stale and stop working but server does not close // them. Thus worker will die after that time of inactivity. WORKER_IDLE_TIMEOUT = time.Minute * 5 )
const (
// Multiplier for message flight queue growth
MESSAGE_FLIGHT_QUEUE_ENLARGE = 0.33
)
Variables ¶
var ( // Client.Send returns this error when caller specified wrong priority. ErrInvalidPriority = errors.New("invalid priority") // Client.Start returns this error when worker counter is not applicable. ErrInvalidWorkerCount = errors.New("worker count must be greater than zero") // Feedback.GetBadTokens return this error when it have been stopped. ErrFeedbackClientStopped = errors.New("feedback client have been stopped") // Client.Send returns this error when payload misses 'aps' section. ErrNoAPS = errors.New("no 'aps' section in payload") // Client.Send returns this error when payload is too large. ErrPayloadIsTooLarge = errors.New("payload exceed 256 bytes") // Client.Send returns this error when token is not well-formed. ErrInvalidTokenLength = errors.New("invalid token length") // worker returns this error when apple returns an unknown error code (should not happen). ErrInvalidAppleResponse = errors.New("invalid apple response") // worker returns this error when idle timeout is reached. ErrIdlingTimeout = errors.New("idle timeout") )
var APNSErrors = map[uint8]string{
0: "No errors",
1: "Processing error",
2: "Missing device token",
3: "Missing topic",
4: "Missing payload",
5: "Invalid token size",
6: "Invalid topic size",
7: "Invalid payload size",
8: "Invalid token",
10: "Shutdown",
255: "Unknown",
}
APNSErrors contains descriptions for error codes.
Functions ¶
This section is empty.
Types ¶
type BadMessageCallback ¶
BadMessageCallback defines function type to call back on messages APNS fails to deliver.
type BadToken ¶
type BadToken struct { // Hex-encoded device token Token string // Timestamp of token expiration date Timestamp time.Time }
BadToken represents entry recieved from feedback service. It contains token and expiration date.
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client is an APNS client. It provides API to send messages, manages message queue, orchestrates workers. It is also used to instantiate feedback service client.
func CreateClient ¶
CreateClient creates Client, loads tls certificate. If parameter 'anyServerCert' is set to true, client will be able to connect to APNS gateway with invalid certificate. Can be used for testing purposes.
After client has been created it should be started using Start() to actually send messages. But even if not having been started it still can be used - all messages will be queued and then sent. It can be handy because workers on startup can take some time to connect to APNS.
func (*Client) Send ¶
func (c *Client) Send(to string, expiry time.Time, priority uint8, payload map[string]interface{}) error
Send enqueues message to delivery. 'to' is a hex-encoded device token, 'expiry' - expiration time of message, 'priority' - either PRIORITY_IMMEDIATE for immediate notification delivery or PRIORITY_DELAYED for background delivery (it is an APNS property. It does not affect client's schedule for message), 'payload' - message payload.
Send will make a message and put it into delivery queue. Thus, Send will return an error only in case of malformed input - invalid token, expiry, priority or payload. Send() to invalid but well-formed token will succeed but later, when actual delivery fails, BadMessageCallback will be invoked.
Client's delivery queue has limited capacity and Send() will block if queue is full. This can happen when workers are overloaded or not yet started.
Send can accept messages before client has been started. Messages will be queued and sent after client startup.
Send does not guarantee ordering of messages sent. Also keep in mind that APNS itself does not guarantee message delivery. However, every sent message either will be 'assumed delivered' to APNS or callback will be called.
func (*Client) SetCallback ¶
func (c *Client) SetCallback(cb BadMessageCallback)
SetCallback sets callback for handling erroneous messages. Every call executed in its own goroutine.
func (*Client) SetupFeedback ¶
SetupFeedback setups feedback client from APNS client config. Feedback client will inherit a certificate and 'anyServerCert' option. After client is created it needs to be started to actually talk to feedback service.
func (*Client) Stop ¶
Stop stops client gracefully. Users should not send messages after invoking Stop; those calls will result in panic. Pending messages will be sent to APNS as usual (callbacks will be invoked for malformed messages). Stop call will return when all pending messages assumed delivered or appropriate callbacks are invoked.
type FeedbackClient ¶
type FeedbackClient struct {
// contains filtered or unexported fields
}
FeedbackClient is a client for APNS Feedback service. It provides API to retrieve device tokens that are no longer valid.
func (*FeedbackClient) GetBadTokens ¶
func (fc *FeedbackClient) GetBadTokens() ([]BadToken, error)
GetBadTokens returns bad tokens retrieved from feedback service. It will block until feedback service sends some tokens or an error occurs.
func (*FeedbackClient) Start ¶
func (fc *FeedbackClient) Start() error
Start starts a client. Will return error if cant resolve feedback service name.