lib/rapns/daemon/apns/delivery.rb
module Rapns
module Daemon
module Apns
class Delivery < Rapns::Daemon::Delivery
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",
255 => "None (unknown error)"
}
def initialize(app, conneciton, notification, batch)
@app = app
@connection = conneciton
@notification = notification
@batch = batch
end
def perform
begin
@connection.write(@notification.to_binary)
check_for_error if Rapns.config.check_for_errors
mark_delivered
Rapns.logger.info("[#{@app.name}] #{@notification.id} sent to #{@notification.device_token}")
rescue Rapns::DeliveryError, Rapns::Apns::DisconnectionError => error
mark_failed(error.code, error.description)
raise
end
end
protected
def check_for_error
if @connection.select(SELECT_TIMEOUT)
error = nil
if tuple = @connection.read(ERROR_TUPLE_BYTES)
_, code, notification_id = tuple.unpack("ccN")
description = APN_ERRORS[code.to_i] || "Unknown error. Possible rapns bug?"
error = Rapns::DeliveryError.new(code, notification_id, description)
else
error = Rapns::Apns::DisconnectionError.new
end
begin
Rapns.logger.error("[#{@app.name}] Error received, reconnecting...")
@connection.reconnect
ensure
raise error if error
end
end
end
end
end
end
end