immobiliare / ApnsPHP

ApnsPHP: Apple Push Notification & Feedback Provider
BSD 3-Clause "New" or "Revised" License
1.43k stars 449 forks source link

Are connections made persistent? #58

Closed AcidicSkittles closed 10 years ago

AcidicSkittles commented 10 years ago

As per apple's best practice guidlines:

When sending notifications, avoid opening and closing the connection with the APN 
service with each notification. Instead, keep your connection to the APN service open
 when sending messages.

I was wondering if this library keeps the connection open to apple's push servers open as long as possible? I.e. if a php script executes and sends a push notification and then 2 seconds later executes again - is it opening and closing the connection over and over or reusing the same one from execution to execution? Looking in abstract.php I see:

    $this->_hSocket = @stream_socket_client($sURL, $nError, $sError,
$this->_nConnectTimeout, STREAM_CLIENT_CONNECT, $streamContext);

But shouldn't STREAM_CLIENT_CONNECT be STREAM_CLIENT_PERSISTENT?

Also, should I be calling

// Disconnect from the Apple Push Notification Service
$push->disconnect();

at then end of every notification if I'm constantly sending notifications?

ctsstc commented 10 years ago

Each time your PHP script gets ran it will try creating a new connection to APNS. If you had a PHP script that was always running you could keep the socket open as long as you needed until either you or Apple closed the connection for whatever reason.

If you're sending that often you should look into batching them together, otherwise you should be just fine opening and closing the connection as needed.

I am interested to hear about STREAM_CLIENT_CONNECT vs STREAM_CLIENT_PERSISTENT because I've seen both used in examples online.

You should be calling disconnect when your script is done or as soon as you're done sending notifications to Apple, especially because the socket will be reopened when the script gets ran again.

I know you're thinking that you want the connection to stay open / persistent between each time your php gets ran, but they're more of talking about consistently reconnecting within the same script, for example I've seen some bad examples where there's a for/foreach loop and each time the connection gets reset in the loop rather than staying open and using the same connection that's already been established.
What you're surely talking/thinking about is on a much more grand scale, thankfully this library takes care of most of the heavy lifting, although you could still improperly code using this library.

There's a few things to consider - opening a secure socket carries some overhead so you want it to be as few as possible. APNS will disconnect you when there's a bad token - so you're going to have to reconnect anyways - this library takes care of that and you can see this happening in the logs - you probably will not see this happening unless you have a big collection of device tokens that have some age to them - I never knew about this until recently, and started to realize how much of a nightmare APNS is compared to GCM which is why I'm so glad this library exists :)

AcidicSkittles commented 10 years ago

Right, right. Thanks for the detailed explanation. I was debating on this library versus having a dedicated daemon run in the background that would always have a single connection open. Think of a messaging style app where users are constantly sending messages back and forth. You would want to send out a notification for every message. I can't help but think I would need a dedicated daemon for that to prevent multiple php scripts running at the same time all opening up connections to send notifications.

I suppose the question is - how many connections and how fast they get opened up is too much?

ctsstc commented 10 years ago

Definately sounds like you could benefit from running a node server, or looking into some more advanced techniques with PHP - last I checked PHP doesn't do threading too easily - it's just missing a lot of features that NodeJS has that you could benefit from using[aync, sockets, "live app"], but maybe with PHP 5.5 it has caught up some.

I'm not much of an iOS/Android developer but have you considered running sockets between the clients and the server? I say this because if I recall correctly Push notifications on either platform do not have guaranteed delivery - they're like UDP vs TCP - which you'd want to select the correct socket for this [TCP] guaranteed delivery with the extra network overhead [if you decided to switch from push notifications to sockets].

I'm not sure what your environment is, but if you wanted to run a PHP socket server I'm sure https://github.com/nodejitsu/forever would help to keep that socket server up and running for you.

It does sound like if you had enough traffic going on you would benefit from having a connection always opened to APNS. You would be able to send as fast as your network and apple's network allowed as well as if they are any limits in place. As for how many concurrent connections, I'm not sure exactly - I've seen people on Stackoverflow saying there are limits and to check out the Documentation, but then I cannot find anything really in the documentation that talks about limits/ip bans.

You either need to handle everything on a single PHP script/instance that runs all the time, or you have one that stays running for communication and then you would need some interprocess communication from the other scripts that run as needed.

It sounds like you've already thought this all through though, interested to hear how it turns out though ;)