Good afternoon, dear habrazhiteli. Most recently, I finished developing an apns-service and would like to share some features of working with it. The article is not a step-by-step instruction, but describes the difficulties and pitfalls that a developer may face. I will give examples of code in Ruby, but everything written is also relevant for other platforms, in particular, PHP.
There are many articles written about the general principles of working with apns, and the official documentation is clear and transparent enough, so let's get straight to the point:
Feature Number Numbers - JSON
It is in this format that you need to convert the message to be sent to the apple server, but here we are disappointed. It would seem the easiest way to generate a message using the built-in array conversion functions in json like this:
result = {} result['aps'] = {} result['aps']['alert'] = m.message result['aps']['badge'] = 0 result['aps']['sound'] = 'default' json = result.to_json
But not everything is so simple. You suddenly find that the maximum length of a text message is only 40-50 characters. Why is that? The fact is that the to_json function in Ruby converts all non-ASCII characters into the / uXXXX sequence, which takes 4 when the message is packed! bytes To bypass this limitation, you need to create a message in plain text format. For example, like this:
json = '{"aps":{"alert":"'+message.gsub(/['"\\\x0]/,'\\\\\0')+'","badge":"'+badge+'","sound":"default"}}'
.gsub(/['"\\\x0]/,'\\\\\0')
- this is an analogue of the addslashes () PHP function. If it is not applied, then messages with punctuation marks and some service characters will not reach the user and the apple will be considered as erroneous.
')
Feature number two - disconnection and feedback
If an error occurred while sending the next message, then the apple simply breaks the connection, not waiting for the end of sending all the messages in the queue. But it is possible to find out what kind of error occurred while sending. To do this, you need to make a message in a special way and assign each one a unique number:
mes = [1,
After sending each message, you need to check whether there is a response from the server, but it is important to remember that if successful, the server returns nothing and if you just wait for the answer, the sending may hang. Error codes are described in the official documentation, so I will not give them here. I will only note that the most common errors are related to the wrong length of the token or the contents of the message.
Feature Three - Feedback
Using this service, Apple returns tokens of devices from which the application has been removed. Many request this information every time they are sent, but this is not necessary. It is enough to contact the service once a day and remove inactive devices from its database. Ignoring this service is also not worth it, because for frequent sending messages to inactive tokens, your service may be blocked.
Feature Number Four - Bulk Messaging
The connection to the apple servers is established using a certificate issued to a specific application. This is how Apple determines to which application on the user's device the sent notification applies. Consequently, to send messages to several applications (namely, this was the task of the service developed by me), it is necessary to create a separate connection for each message array. A common mistake made by developers - they try to send messages in small batches of 100-200 pieces, each time creating and breaking the connection. This can be perceived by the server as an attack attempt and your service will be blocked. To avoid this, you need to send all messages through one connection, even if there are several tens of thousands. And from here follows feature number six.
Feature number six - time is our enemy
With a large number of messages, the execution time of the send script can be quite long and on most servers the execution will be completed by a timeout of 30 seconds. The solution is to separate the logic of creating and sending messages. I did this with the help of a daemon (
gem daemons is responsible for this in ROR. Through the web interface, the text is added to the database and a filter, by which tokens will be selected from the database when sent, and the demon every 10 seconds polls the database for new tasks and sends messages In such an implementation, there is one more indisputable advantage - we can set up a delayed sending of messages.
Conclusion
In spite of all the pitfalls and subtleties that need to be remembered, the implementation of the apple push message service is done at the highest level. The service is fast, convenient and requires a minimum of resources to send a huge amount of the message. For example: To send 15,000 messages, we need to transfer to the server only about 3.5-4 megabytes of data.