18

I am using PHP to connect to apns to send some notifications to multiple devices, although the question is more conceptual so it doesn't have to be specific to PHP.

I will be sending to about 7000 devices (and growing) all at the same time. My process runs ONCE per day and broadcasts to all devices, so I am not constantly re-opening a connection.

Currently I can easily send to 2 devices at a time and the messages will successfully deliver. However when I attempt to send to the full 7000 devices, the messages do not seem to deliver.

The pseudo-logic to my code is:

open connection to apple
loop over device-tokens
    write to socket connection per device
end loop
close connection to apple.

I have seen somewhere that I should only perform a SINGLE write, and construct one huge body, in other words the pseudo-code would look like:

loop over device tokens
    create payload aggregating all devices
end loop
open connection to apple
write to socket ONCE with whole payload for 7000 devices
close connection

It's difficult to test as I obviously can't spam my 7000 production users with test messages. Has anybody else had a similar problem?

Thanks

BoomShaka
  • 1,571
  • 7
  • 27
  • 40
  • did you ever get this working? I will soon be writing an app that will be facing the same issue -- broadcast to thousands of clients through APNS. – Mike Morearty Oct 01 '10 at 16:56
  • 3
    Hi Mike. Yes I did. The implementation at the time that i posted this question was in the fairly early stages. The problem was that I had some sandbox devices in the same table as production devices. Apple sometimes drops the connection if you send to a sandbox device_token while using production certs. So the simple solution is to just verify that the correct number of bytes was written to the connection and that the connection has not dropped after every write event. If it drops you have to re-open the connection and continue from where you left off. good luck! – BoomShaka Oct 02 '10 at 13:23
  • FYI, you can open the connection and perform as many writes as you like. just make sure you check the connection status after each write – BoomShaka Oct 02 '10 at 13:28
  • is it possible to broadcast push message to multiple devices? Can i aggregate the tokens as you mentioned above and send one message to all devices? – Itay Levin Jul 27 '11 at 11:56
  • 1
    Err yes, that's exactly what I'm doing above. I collect all the tokens in a database table, and then once per week I send the same message to all devices (the message could even be customised per device. You will have to send a seperate payload to the APNS per device though. SO if you have 100 devices, thats 100 writes to the socket – BoomShaka Aug 02 '11 at 16:45
  • and how many writes can I send in one transmission, 10K is ok? do I have to worry about it? – AmineG Aug 23 '11 at 22:39
  • I don't know unfortunately, I guess it is irrelevant though, as long as you check the number of bytes written, and the connection status after EACH write, you can simply re-open the connection and continue from where you left off if the connection drops. – BoomShaka Aug 25 '11 at 10:38
  • Hello @BoomShaka! I just ran into the same problem. Could you post the code to check state and reconnect? I can't get its working… – Julian F. Weinert Oct 30 '12 at 18:40
  • Check this question http://stackoverflow.com/q/14563097/1868660 – Subodh Ghulaxe May 06 '13 at 06:44

2 Answers2

6

I've read that apple does care about the number of connections you make to their servers but I've never heard about any write limits. Also, I'm not sure about what kind of response you'd receive here, but it might be worth a try to see what happens. Maybe experiment with the sandbox push notification server, only using the device tokens of the production devices. Those phones should not receive any push notifications sent to the sandbox server and if the sandbox reports "delivered successfully", that would be a worry-free way to test.

jtrim
  • 3,465
  • 4
  • 31
  • 44
  • way overdue. but your answer was essentially correct. thanks :) – BoomShaka Oct 02 '10 at 13:53
  • The sandbox needs development certificate and the production needs production certificates. APNS document says that the device tokens that are generated for development(sandbox environment) build are totally different than production build. Also that APNS production build if gets a device token generated by development build directly invalidates the device token and drops the connection. So the status wont be successful but the connection will be dropped. For testing mocking the APNS service is a better option. – Apurv Nerlekar Jun 28 '13 at 11:38
0

I see what you want and rather, i did face the same problem, what worked for me was the reverse engineering. I just looked into the library and checked for the function which validates the deviceToken. So while creation of dummy device token i just made sure that the generated token is valid as per the library.

The following code will let you generate valid device Tokens, now its on you to how many millions of tokens to generate using this function.

   def generateRandomDeviceTokenAndAppendItToJson(tokenLength: Int) {
     val randomlyGeneratedDeviceToken = new StringBuilder()
      randomlyGeneratedDeviceToken.append("          \"")
        (1 to tokenLength) foreach {
         times: Int =>
        if (tokenLength equals Device.Apple)
         randomlyGeneratedDeviceToken.append(validCharacter().toString.charAt(0))
        else
         randomlyGeneratedDeviceToken.append(Random.alphanumeric.head)
        }
       randomlyGeneratedDeviceToken.append("\",")
       println(randomlyGeneratedDeviceToken)
       writer.write(randomlyGeneratedDeviceToken.toString())
      }

      private def validCharacter(): Int = {
       val a = Random.alphanumeric.head
       if ('0' <= a && a <= '9')
        return (a - '0')
       else if ('a' <= a && a <= 'f')
        return ((a - 'a') + 10)
       else if ('A' <= a && a <= 'F')
        return ((a - 'A') + 10)
       validCharacter() 
     }

The apple deviceToken is of 64 character so you will need to iterate on it for 64 times.

Apurv Nerlekar
  • 2,310
  • 1
  • 21
  • 29
  • I doubt this can work. You may have reverse engineered a low level validation which just checks the correctness of a token *to some extent*. But that's just the first defense line of Apple to prevent any spamming. I could bet in a million dollar that you cannot send out messages in the wild to random deviceTokens. Apple would shut you down pretty quickly. Even if it would work with the sandbox server, such test wouldn't prove anything in my opinion. – Csaba Toth Sep 08 '15 at 05:36
  • BTW, there wasn't any validation? Because from your code it looks like it simply generates a 64 character length of string of *completely random* hex characters. No constraints whatsoever. – Csaba Toth Sep 23 '15 at 17:06
  • Agreed Csaba Toth, this does generate random 64 char length string, but the validation(see valid character function above) is the same(it took me to analyze tokens rather than find it somewhere on the net) what apns does at its end, and it did work for me to test my server for performance. Give it a try, and try sending it to apns, it would report valid. Ofcourse, it could be actual tokens generated, we should be courteous enough to send it on sandbox environment, else as you said it would be spamming. – Apurv Nerlekar Oct 21 '15 at 05:22
  • What do you mean by reporting it valid? Just because APNS sandbox server consumes it doesn't mean that it's valid. I think APNS server's goal is to consume anything you throw at it, otherwise it would decrease performance of the users of the service. Then under the hood they may diss the token. It will all turn out in the live APNS server when you request a feedback, and you'll get back the list of the invalid invalid/expired tokens. – Csaba Toth Oct 22 '15 at 03:02
  • Whatever user land library you looked at it doesn't mean that the validation is the same as the validation what the APNS server does. Especially after looking at the code, there's no real validation here, all alphanumeric random bitstrings with the given length will let through. The library's "validation" is only for discard the obviously malformed ids. – Csaba Toth Oct 22 '15 at 03:05
  • However, maybe this could still be used for performance measurement of the sending part of your app, measuring the performance of the APNS sending library. – Csaba Toth Oct 22 '15 at 03:05
  • No, So the sandbox does not take in what ever is thrown to it. The token need to be in a specific valid constraints, I have tried to send APNS a wrong token, and it just dropped the complete batch of push notifications. This is useful when you want to test your sending part(server) for the performance tuning. – Apurv Nerlekar Oct 23 '15 at 21:57
  • Also, It does not report in the feedback service as a bad token..I would strongly suggest you to give it a try. :) – Apurv Nerlekar Oct 23 '15 at 22:03