Class: Pushr::Daemon::ApnsSupport::ConnectionApns
- Inherits:
-
Object
- Object
- Pushr::Daemon::ApnsSupport::ConnectionApns
- Defined in:
- lib/pushr/daemon/apns_support/connection_apns.rb
Constant Summary collapse
- IDLE_PERIOD =
30 * 60
- SELECT_TIMEOUT =
0.2
- ERROR_TUPLE_BYTES =
6
- APN_ERRORS =
{ 1 => 'Processing error', 2 => 'Missing device token', 3 => 'Missing topic', 4 => 'Missing payload', 5 => 'Missing token size', 6 => 'Missing topic size', 7 => 'Missing payload size', 8 => 'Invalid token', 10 => 'Shutdown (APNS is in maintenance)', 255 => 'None (unknown error)' }
Instance Attribute Summary collapse
-
#configuration ⇒ Object
readonly
Returns the value of attribute configuration.
-
#last_write ⇒ Object
Returns the value of attribute last_write.
-
#name ⇒ Object
readonly
Returns the value of attribute name.
Instance Method Summary collapse
- #check_for_error(notification) ⇒ Object
- #close ⇒ Object
- #connect ⇒ Object
- #initialize(configuration, i = nil) ⇒ ConnectionApns constructor
- #read(num_bytes) ⇒ Object
- #reconnect ⇒ Object
- #select(timeout) ⇒ Object
- #write(data) ⇒ Object
Constructor Details
#initialize(configuration, i = nil) ⇒ ConnectionApns
25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
# File 'lib/pushr/daemon/apns_support/connection_apns.rb', line 25 def initialize(configuration, i = nil) @configuration = configuration if i # Apns push connection @name = "#{@configuration.app}: ConnectionApns #{i}" @host = "gateway.#{configuration.sandbox ? 'sandbox.' : ''}push.apple.com" @port = 2195 else @name = "#{@configuration.app}: FeedbackReceiver" @host = "feedback.#{configuration.sandbox ? 'sandbox.' : ''}push.apple.com" @port = 2196 end written end |
Instance Attribute Details
#configuration ⇒ Object (readonly)
Returns the value of attribute configuration.
7 8 9 |
# File 'lib/pushr/daemon/apns_support/connection_apns.rb', line 7 def configuration @configuration end |
#last_write ⇒ Object
Returns the value of attribute last_write.
8 9 10 |
# File 'lib/pushr/daemon/apns_support/connection_apns.rb', line 8 def last_write @last_write end |
#name ⇒ Object (readonly)
Returns the value of attribute name.
7 8 9 |
# File 'lib/pushr/daemon/apns_support/connection_apns.rb', line 7 def name @name end |
Instance Method Details
#check_for_error(notification) ⇒ Object
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 |
# File 'lib/pushr/daemon/apns_support/connection_apns.rb', line 91 def check_for_error(notification) # check for true, because check_for_error can be nil return if @configuration.skip_check_for_error == true if select(SELECT_TIMEOUT) error = nil if tuple = read(ERROR_TUPLE_BYTES) _, code, notification_id = tuple.unpack('ccN') if code.to_i == 8 Pushr::FeedbackApns.create(app: @configuration.app, device: notification.device, follow_up: 'delete', failed_at: Time.now) Pushr::Daemon.logger.info("[#{@name}] Invalid device (error 8), feedback sent, message delivery failed"\ " to #{notification.to_json}") else description = APN_ERRORS[code.to_i] || 'Unknown error. Possible push bug?' error = Pushr::Daemon::DeliveryError.new(code, notification, description, 'APNS') end else error = DisconnectionError.new end begin Pushr::Daemon.logger.error("[#{@name}] Error received, reconnecting...") reconnect ensure fail error if error end end end |
#close ⇒ Object
47 48 49 50 51 |
# File 'lib/pushr/daemon/apns_support/connection_apns.rb', line 47 def close @ssl_socket.close if @ssl_socket @tcp_socket.close if @tcp_socket rescue IOError end |
#connect ⇒ Object
40 41 42 43 44 45 |
# File 'lib/pushr/daemon/apns_support/connection_apns.rb', line 40 def connect @ssl_context = setup_ssl_context @tcp_socket, @ssl_socket = connect_socket rescue Pushr::Daemon.logger.error("#{@name}] Error connection to server, invalid certificate?") end |
#read(num_bytes) ⇒ Object
53 54 55 |
# File 'lib/pushr/daemon/apns_support/connection_apns.rb', line 53 def read(num_bytes) @ssl_socket ? @ssl_socket.read(num_bytes) : false end |
#reconnect ⇒ Object
86 87 88 89 |
# File 'lib/pushr/daemon/apns_support/connection_apns.rb', line 86 def reconnect close @tcp_socket, @ssl_socket = connect_socket end |
#select(timeout) ⇒ Object
57 58 59 |
# File 'lib/pushr/daemon/apns_support/connection_apns.rb', line 57 def select(timeout) IO.select([@ssl_socket], nil, nil, timeout) end |
#write(data) ⇒ Object
61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
# File 'lib/pushr/daemon/apns_support/connection_apns.rb', line 61 def write(data) reconnect_idle if idle_period_exceeded? retry_count = 0 begin write_data(data) rescue Errno::EPIPE, Errno::ETIMEDOUT, Errno::ECONNRESET, OpenSSL::SSL::SSLError => e retry_count += 1 if retry_count == 1 Pushr::Daemon.logger.error("[#{@name}] Lost connection to #{@host}:#{@port} (#{e.class.name}), reconnecting...") end if retry_count <= 3 reconnect sleep 1 retry else raise ConnectionError, "#{@name} tried #{retry_count - 1} times to reconnect but failed (#{e.class.name})." end end check_for_error(data) end |