Class: LeadZeppelin::APNS::Gateway
- Inherits:
-
Object
- Object
- LeadZeppelin::APNS::Gateway
- Defined in:
- lib/lead_zeppelin/apns/gateway.rb
Constant Summary collapse
- HOST =
'gateway.push.apple.com'
- SANDBOX_HOST =
'gateway.sandbox.push.apple.com'
- PORT =
2195
- DEFAULT_TIMEOUT =
10
- DEFAULT_SELECT_WAIT =
0.3
Instance Method Summary collapse
- #connect ⇒ Object
- #disconnect ⇒ Object
-
#initialize(ssl_context, opts = {}) ⇒ Gateway
constructor
A new instance of Gateway.
- #process_error(notification = nil) ⇒ Object
- #reconnect ⇒ Object
- #write(notification) ⇒ Object
Constructor Details
Instance Method Details
#connect ⇒ Object
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
# File 'lib/lead_zeppelin/apns/gateway.rb', line 19 def connect Logger.thread 's' begin timeout(@opts[:timeout] || DEFAULT_TIMEOUT) do socket = TCPSocket.new (@opts[:host] || HOST), (@opts[:port] || PORT) socket.setsockopt Socket::SOL_SOCKET, Socket::SO_KEEPALIVE, true ssl_socket = OpenSSL::SSL::SSLSocket.new socket, @ssl_context ssl_socket.sync_close = true # when ssl_socket is closed, make sure the regular socket closes too. ssl_socket.connect # FIXME TODO CHECK FOR EOFError HERE instead of in process_error @socket = socket @ssl_socket = ssl_socket end Logger.debug "gateway connection established" rescue Errno::ETIMEDOUT, Timeout::Error Logger.warn "gateway connection timeout, retrying" retry end end |
#disconnect ⇒ Object
53 54 55 56 57 |
# File 'lib/lead_zeppelin/apns/gateway.rb', line 53 def disconnect Logger.info "disconnecting from gateway" Logger.thread 'd' @ssl_socket.close end |
#process_error(notification = nil) ⇒ Object
59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
# File 'lib/lead_zeppelin/apns/gateway.rb', line 59 def process_error(notification=nil) begin error_response = @ssl_socket.read_nonblock 6 error = ErrorResponse.new error_response, notification Logger.warn "error: #{error.code}, #{error.identifier.inspect}, #{error.}" Logger.thread 'e' reconnect if !@opts[:notification_error_block].respond_to?(:call) Logger.warn "You have not implemented an on_notification_error block. This could lead to your account being banned from APNS. See the APNS docs" else @opts[:notification_error_block].call(error) end rescue EOFError # FIXME put in a certificate error pre-check and perhaps an error block for handling this. # A better solution is the remove the application altogether from the client.. # Sometimes this just means that the socket has disconnected. Apparently Apple does that too. # Logger.info "socket has closed for #{@opts[:application_identifier]}, reconnecting" reconnect rescue IO::WaitReadable # No data to read, continue Logger.thread 'g' end end |
#reconnect ⇒ Object
46 47 48 49 50 51 |
# File 'lib/lead_zeppelin/apns/gateway.rb', line 46 def reconnect Logger.info "reconnecting to gateway" Logger.thread 'r' disconnect connect end |
#write(notification) ⇒ Object
88 89 90 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 |
# File 'lib/lead_zeppelin/apns/gateway.rb', line 88 def write(notification) Logger.thread 'w' begin process_error @ssl_socket.write notification.payload read, write, error = IO.select [@ssl_socket], [], [@ssl_socket], (@opts[:select_wait] || DEFAULT_SELECT_WAIT) if !error.nil? && !error.first.nil? Logger.error "IO.select has reported an unexpected error. Reconnecting, sleeping a bit and retrying" sleep 1 reconnect end if !read.nil? && !read.first.nil? process_error(notification) return false end rescue Errno::EPIPE => e Logger.warn 'gateway connection returned broken pipe, attempting reconnect and retrying' Logger.thread 'f' reconnect retry end true end |