

Grocer - New Gem for Sending Apple Push Notifications in Ruby - vanstee
https://github.com/highgroove/grocer

======
kyledrake
Awesome! This is great.

I'm also working on an APNS gem called Lead Zeppelin, which is similar in
design, but adds a few things like a pool of connections (read: concurrent on
threaded systems like JRuby and Rubinius):
<https://github.com/geoloqi/lead_zeppelin>

There is some high quality code here, this is a great start. I think the error
handling needs to be drilled down a bit, and there needs to be more logging.
I'm definitely going to borrow some components of this.. the apns test server
is really awesome! I'm happy that APNS support is improving in the Ruby
community.

~~~
vanstee
Great suggestions. It would be awesome if you contributed it to grocer as well
:P. It's still in active development though so you may find some of these
enhancements in grocer at some point in the near future. Thanks man!

~~~
kyledrake
No problem, I would love to contribute! My account is kyledrake on Github.

Right now I'm experimenting with socket keepalive, which I think may be
important to keeping socket connections open (per some discussion I found from
an Apple dev). If my tests go well I'll send a pull request later tonight!

The one thing I haven't figured out yet is how to stop messages from being
dropped after feedback comes in. It has a tendency to silently fail to send
messages. My current solution is to check for errors before a write, and do a
IO.select on the socket to wait for a read for an arbitrary amount of time.
You might want to look at some of the weird stuff I had to do in here.. it's a
problem I'd like to figure out how to deal with:
[https://github.com/geoloqi/lead_zeppelin/blob/master/lib/lea...](https://github.com/geoloqi/lead_zeppelin/blob/master/lib/lead_zeppelin/apns/gateway.rb#L96)

~~~
vanstee
Sweet. Now accepting pull requests :)

Interesting. We haven't hit that issue yet.

Hmmm. We also haven't had any issues with feedback affecting our outgoing
messages. Yeah we just check for messages from the feedback socket after
sending a notification (as Apple's guide recommends) but we're not doing
anything fancy like waiting for a response. Sounds cool though.

~~~
kyledrake
I want to remove the IO.select because it slows things down unfortunately. I
noticed you are using enhanced push, but also opening a feedback socket
separately. I was under the impression that you were supposed to read feedback
in-line with the enhanced protocol, but I may have gotten this wrong. Are you
using the enhanced protocol -and- listening to the feedback socket? This is
interesting, and may solve a problem I'm having, so I wanted to get your
thoughts.

~~~
vanstee
Couldn't find that in the guide (reading feedback from the same socket). I
might have missed it though.

And yep. We're using the enhanced protocol while opening another connection to
the feedback service. I just followed this section of the docs.

[http://developer.apple.com/library/mac/#documentation/Networ...](http://developer.apple.com/library/mac/#documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/CommunicatingWIthAPS/CommunicatingWIthAPS.html#//apple_ref/doc/uid/TP40008194-CH101-SW3)

------
juliennakache
Hey, you do know that Apple requires developers to maintain persistent
connections to their servers, right?

Checkout <https://github.com/jnak/apnmachine> Feature list: \- persistent
connection to APN Servers (as Apple recommends) \- real-time notifications (no
regular polling a la Resque) \- super easy to use in Ruby and any languages
(as easy as enqueuing a serialized JSON hash in Redis) \- persist and queue
messages when server is down \- horizontal scalability and out-of-the-box
load-balancing \- fast daemons

~~~
vanstee
Nice! We keep a single connection open using the standalone gem.

But yeah you're right it would be an issue if you were connecting to Apple's
servers in a resque worker for example, since the socket would be opened in a
new child for each job. I bet you could get around this though by opening a
socket in the parent and using it in each child process. Reconnecting might be
a little trickier though.

apnmachine looks pretty sweet. I'll have to check it out if I need something
like that in the future.

~~~
juliennakache
Don't know the standalone gem, I'll have to check that out. I'll be glad to
get some feedback on apnmachine :)

~~~
stevenharman
> the standalone gem

@vanstee is referring the Grocer being a RubyGem and not needing other
dependencies like Resque.

------
aaronbrethorst
Or, if you use Urban Airship; it's literally like five lines of code with
HTTParty to send a push notification.

Of course, your needs may vary, but UA scales well and is essentially free to
start with.

~~~
tstyle
I was just looking at options for push notifications in ruby. I found a gem
called apn_on_rails (<https://github.com/PRX/apn_on_rails>) which sort of
worked. But I didn't know how to keep persistent connections and was afraid of
accidentally spamming Apple's servers. I thought about outsource the problem
to Urban Airship, but unfortunately their free service only works for 45 days
then costs hundreds of dollars a month. Grocer looks really interesting and
I'd definitely want to try it out.

~~~
aaronbrethorst
You scared me there for a minute. I thought they'd dropped their free plan.
Turns out it still exists: <https://go.urbanairship.com/accounts/register/>

