Class: APN::Sender
- Inherits:
-
Resque::Worker
- Object
- Resque::Worker
- APN::Sender
- Includes:
- Connection::Base
- Defined in:
- lib/apn/sender.rb
Overview
Subclass of Resque::Worker which initializes a single TCP socket on creation to communicate with Apple’s Push Notification servers. Shares this socket with each child process forked off by Resque to complete a job. Socket is closed in the before_unregister_worker callback, which gets called on normal or exceptional exits.
End result: single persistent TCP connection to Apple, so they don’t ban you for frequently opening and closing connections, which they apparently view as a DOS attack.
Accepts :environment
(production vs anything else) and :cert_path
options on initialization. If called in a Rails context, will default to RAILS_ENV and RAILS_ROOT/config/certs. :environment will default to development.
APN::Sender expects two files to exist in the specified :cert_path
directory: apn_production.pem
and apn_development.pem
.
If a socket error is encountered, will teardown the connection and retry again twice before admitting defeat.
Constant Summary collapse
- TIMES_TO_RETRY_SOCKET_ERROR =
2
Instance Attribute Summary
Attributes included from Connection::Base
Instance Method Summary collapse
-
#send_to_apple(notification, attempt = 0) ⇒ Object
Send a raw string over the socket to Apple’s servers (presumably already formatted by APN::Notification).
Methods included from Connection::Base
#initialize, #resque_log, #socket
Methods inherited from Resque::Worker
#run_hook, #unregister_worker, #unregister_worker_without_before_hook
Instance Method Details
#send_to_apple(notification, attempt = 0) ⇒ Object
Send a raw string over the socket to Apple’s servers (presumably already formatted by APN::Notification)
20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
# File 'lib/apn/sender.rb', line 20 def send_to_apple( notification, attempt = 0 ) if attempt > TIMES_TO_RETRY_SOCKET_ERROR log_and_die("Error with connection to #{apn_host} (retried #{TIMES_TO_RETRY_SOCKET_ERROR} times): #{error}") end self.socket.write( notification.to_s ) rescue SocketError => error log(:error, "Error with connection to #{apn_host} (attempt #{attempt}): #{error}") # Try reestablishing the connection teardown_connection setup_connection send_to_apple(notification, attempt + 1) end |