class ApnsProviderApi::Client
Attributes
certificate[RW]
feedback_uri[RW]
gateway_uri[RW]
passphrase[RW]
split_size[RW]
timeout[RW]
Public Class Methods
development()
click to toggle source
# File lib/apns_provider_api/client.rb, line 15 def development client = self.new client.gateway_uri = APPLE_DEVELOPMENT_GATEWAY_URI client end
mock()
click to toggle source
# File lib/apns_provider_api/client.rb, line 27 def mock client = self.new client.gateway_uri = "apn://127.0.0.1:2195" client end
new()
click to toggle source
# File lib/apns_provider_api/client.rb, line 34 def initialize @gateway_uri = ENV['APN_GATEWAY_URI'] @certificate = File.read(ENV['APN_CERTIFICATE']) if ENV['APN_CERTIFICATE'] @passphrase = ENV['APN_CERTIFICATE_PASSPHRASE'] @pid = Process.pid @failed_notifications, @failed_streams, @notifications = [], [], [] end
production()
click to toggle source
# File lib/apns_provider_api/client.rb, line 21 def production client = self.new client.gateway_uri = APPLE_PRODUCTION_GATEWAY_URI client end
Public Instance Methods
enqueue(notifications)
click to toggle source
# File lib/apns_provider_api/client.rb, line 42 def enqueue(notifications) @split_size ||= 500 notifications.each_slice(@split_size) do |group| push(group) end @failed_notifications end
increase_counter()
click to toggle source
# File lib/apns_provider_api/client.rb, line 125 def increase_counter @counter += 1 end
push(notifications)
click to toggle source
# File lib/apns_provider_api/client.rb, line 50 def push(notifications) return if notifications.empty? @notifications = notifications.flatten @counter = 0 head = { ':scheme' => 'https', ':method' => 'POST' # ':apns-expiration' => 0 #do not store for sending late #'content-length' => notification.message.size } Connection.open(@gateway_uri, @certificate, @passphrase) do |connection| ssl_sock = connection.ssl # events(connection.http2client, ssl_sock) @notifications.each_with_index do |notification, index| connection.open? head[':path'] = "/3/device/#{notification.token}" head[':apns-id'] = notification.uuid stream = connection.new_stream # because apple is not returning the uuid when push fails, # i'm replacing uuid to stream id notification.uuid = stream.id stream.on(:headers) do |h| # puts "headers: #{h} - stream_id: #{stream.id}" read_headers(Hash[*h.flatten], stream) end stream.on(:data) do |d| # puts "data: #{d}" # puts "#{JSON.parse(d)} - #{stream.id.to_s}" read_body(JSON.parse(d), stream) end stream.headers(head, end_stream: false) stream.data(notification.payload.to_json) end # keep_reading = true while !ssl_sock.closed? && !ssl_sock.eof? data = ssl_sock.read_nonblock(1024) # puts "Received bytes: #{data.unpack("H*").first}" begin connection.http2client << data return if @counter == @notifications.size rescue => e puts "Exception: #{e}, #{e.message} - closing socket." ssl_sock.close end end end end
read_body(response, stream)
click to toggle source
# File lib/apns_provider_api/client.rb, line 117 def read_body(response, stream) increase_counter return unless @failed_streams.include?(stream) notification = @notifications.select{|n| n.uuid == stream.id}[0] notification.error_message = response['reason'] @failed_notifications << notification end
read_headers(headers, stream)
click to toggle source
# File lib/apns_provider_api/client.rb, line 107 def read_headers(headers, stream) # puts headers[':status'] if headers[':status'].to_i == 200 # when notification succeeds, we wont receive body increase_counter else @failed_streams << stream end end