Skip to content

Related projects #53

@nathany

Description

@nathany

For a little inspiration, I'm taking a look at other Go projects for APNS, starting with the one @finkel mentioned in #47 and then the one @themartorana mentioned (#38). @willfaught mentioned anachronistic in #26 (comment).

apns by Pranav Raja @pranavraja https://github.com/pranavraja/apns

  • Exposes a queue (a slice) for sending multiple notifications at once. Timehop has an internal circular buffer rather than exposing a queue. Currently neither implementation batches multiple notifications into a single frame.
  • It uses the synchronous approach of sending a batch, then reading with a timeout. Timehop does the read on a separate goroutine. Based on Apple's documentation I believe the separate goroutine to be more responsive, though reading with a timeout does make for a nice and simple synchronous API.
  • Rather than resend failed messages internally, it reports what was unsent and reslices the queue for resending (less magic).
  • There is a timeout parameter for sending. 👍
  • Exposes a lower-level API to read errors from the socket and decode the Apple format. This is an interesting alternative to passing those errors over a channel. Timehop does a blocking read in a goroutine and sends errors over FailedNotifs, but a blocking read in a goroutine could be part of the client code or a high-level API.
  • Offers a lower-level interface where you can make a notification before sending it.
  • Notification is a separate package. 👍
  • MakeNotification takes a string rather than defining the structs for JSON serialization.

SendOne, MakeNotification, and ReadInvalid make for a nice lower-level API that other things can be built on. I'm not sure how I feel about the queue. If I was fanning-out the same/similar message to a number of devices or using it as a mechanism for batch & send, maybe it could work, but managing multiple queues at once (requeuing on errors while sending more messages) could become cumbersome for the client.

go-libapns by Karl Kirch @joekarl https://github.com/joekarl/go-libapns

  • Batches push notifications up to 64K (TCP packet size) and flushes every 10ms. This is accomplished with an internal inFlightFrameByteBuffer.
  • Doesn't use Nagel Using Nagle's algorithm? #32 in order to have a shorter timeout length (REAMDE includes explanation)
  • Provides two functions for creating connections, one takes an existing tcp net.Conn for use on Google App Engine, etc.
  • API uses channels (SendChannel) rather than a Send() method (Timehop currently puts a notification into an internal channel). Also uses a runLoop called sendListener.
  • When an error occurs, it sends the notification that failed and all the unset notifications over a CloseChannel.
  • To clear badges, it was relying on negative numbers (instead of 0), but now uses BadgeNumber from @themartorana. See Move away from pointers for badge field? #38.
  • It will clip the alert body if the payload is over Apple's 2K limit.

apns by @anachronistic https://github.com/anachronistic/apns

  • Alert uses an interface that can be either a string or an AlertDictionary. Timehop currently checks if only Alert.Body is set and serializes the JSON in the more efficient way, but the API still requires an Alert struct.
  • It has a PayloadString() for serializing the JSON without doing the binary encoding or sending it.
  • It connects, writes and waits for a response (with a timeout) all in one step. This may be fine for very low-volume push notifications, but Apple treats rapid connection and disconnection as a denial-of-service attack.
  • Overrides Badge 0 to -1 (not sure the point, vs just not using omitempty). Not sure if it's possible to leave badge as-is (omitempty)?
  • Does a check for MaxPayloadSizeBytes and returns an error. Timehop does not.
  • Generates a pseudo-random identifier up to 9999 rather than incrementing a counter or requesting it from the caller.

apns by Arash Payan @arashpayan https://github.com/arashpayan/apns

  • Uses a pseudo-random identifier like anachronistic.
  • Uses a slice to store the last 25 notifications (rather than a list). Hm.
  • Uses an invalidTokenHandler callback
  • Exponential backoff for reconnects.

apns by Ryan Slade @ryanslade https://github.com/ryanslade/apns

  • Has a shortcut for pushing a message with just an alert (PushMessage).
  • Uses an idChan to generate incrementing identifiers
  • Launches a go routine to resend payloads on failure.
  • Holds on to a slice of payloads and cleans them up after 5 minutes rather than using a circular list that limits the amount.

apns on App Engine by Siong @siong1987 https://github.com/siong1987/apns

  • This uses appengine.Context and appengine/socket.
  • It has it's own PEM loader that supports keys with a passphrase.
  • Uses the synchronous read after writing method.
  • Has a connection pool (10 connections to Apple).
  • Uses a pseudo-random identifier like anachronistic.

hermes APNS/GCM by Paul Karadimas @pkar https://github.com/pkar/hermes

Go-APNs by Matthew Price @mattprice https://github.com/mattprice/Go-APNs

apns-go by @Kwik-messenger https://github.com/Kwik-messenger/apns-go

go_apns by @MessageDream https://github.com/MessageDream/go_apns

Go-Apns by @virushuo Ju Huo https://github.com/virushuo/Go-Apns

  • The example is interesting in that mutates an existing payload, yet Send takes a pointer to a notification. Hm.
  • Overall a similar architecture with a sendLoop and reconnecting. It also uses an errorChan for reporting errors (but of type error) and a concrete NotificationError struct with an OtherError for storing read errors, etc.

APNs by Cornel Damian @corneldamian https://github.com/corneldamian/APNs

APNs by Matt DuVall @mduvall https://github.com/mduvall/go-apns

go-apns by Fabrizio Milo @Mistobaan https://github.com/Mistobaan/go-apns

Apns by @houxiaobei https://github.com/houxiaobei/Apns

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions