Class: APN::Client

Inherits:
Object
  • Object
show all
Defined in:
lib/apn/client.rb

Instance Method Summary collapse

Constructor Details

#initialize(options = {}) ⇒ Client

Returns a new instance of Client.



6
7
8
9
10
11
# File 'lib/apn/client.rb', line 6

def initialize(options = {})
  @cert = options[:cert]
  @password = options[:password]
  @host = options[:host]
  @port = options[:port]
end

Instance Method Details

#connect!Object



13
14
15
16
17
18
19
20
21
22
# File 'lib/apn/client.rb', line 13

def connect!
  APN.log(:info, 'Connecting...')

  cert = self.setup_certificate
  @socket = self.setup_socket(cert)

  APN.log(:info, 'Connected!')

  @socket
end

#feedbackObject



78
79
80
81
82
83
# File 'lib/apn/client.rb', line 78

def feedback
  if bunch = socket.read(38)
    f = bunch.strip.unpack('N1n1H140')
    APN::FeedbackItem.new(Time.at(f[0]), f[2])
  end
end

#push(notification) ⇒ Object



55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/apn/client.rb', line 55

def push(notification)
  begin
    APN.log(:info, "Sending #{notification.device_token}: #{notification.json_payload}")
    socket.write(notification.to_bytes)
    socket.flush

    if IO.select([socket], nil, nil, 1) && error = socket.read(6)
      error = error.unpack('ccN')
      APN.log(:error, "Encountered error in push method: #{error}, backtrace #{error.backtrace}")
      return false
    end

    APN.log(:info, 'Message sent')

    true
  rescue OpenSSL::SSL::SSLError, Errno::EPIPE => e
    APN.log(:error, "Encountered error: #{e}, backtrace #{e.backtrace}")
    APN.log(:info, 'Trying to reconnect...')
    reset_socket
    APN.log(:info, 'Reconnected')
  end
end

#reset_socketObject



44
45
46
47
48
49
# File 'lib/apn/client.rb', line 44

def reset_socket
  @socket.close if @socket
  @socket = nil

  connect!
end

#setup_certificateObject



24
25
26
27
28
29
30
31
32
# File 'lib/apn/client.rb', line 24

def setup_certificate
  APN.log(:info, 'Setting up certificate...')
  @context      = OpenSSL::SSL::SSLContext.new
  @context.cert = OpenSSL::X509::Certificate.new(File.read(@cert))
  @context.key  = OpenSSL::PKey::RSA.new(File.read(@cert), @password)
  APN.log(:info, 'Certificate created!')

  @context
end

#setup_socket(ctx) ⇒ Object



34
35
36
37
38
39
40
41
42
# File 'lib/apn/client.rb', line 34

def setup_socket(ctx)
  APN.log(:info, 'Connecting...')

  socket_tcp = TCPSocket.new(@host, @port)
  OpenSSL::SSL::SSLSocket.new(socket_tcp, ctx).tap do |s|
    s.sync = true
    s.connect
  end
end

#socketObject



51
52
53
# File 'lib/apn/client.rb', line 51

def socket
  @socket ||= connect!
end