Skip to content

Loading…

Fix for feedback method #13

Merged
merged 1 commit into from

3 participants

@MichaelBaker

I had to make a change to this repo in order to get feedback working for our project. It now reads messages correctly from the APNS feedback service. Would you mind merging in my changes and bumping up the version on Rubygems?

@NicosKaralis

i still cant read the feedback from my app
on your code and on the "official" code

it just returns a empty array all the time

@MichaelBaker

Have you verified that the SSL connection is being established successfully? Can your SSL connection read anything?

@NicosKaralis

Yes, i can send notifications, because the two methods (open_connection, and open_feedback_connection) are the same i can't see why the ssl connection is not being opened.

And my connection sometimes read something. The problem is: the bytes read are not compatible with apple documentation.

The minimum number of bytes read are 38 and the first 4 are a timestamp, the 5º are a number and the other are the token. But the token always change, and the timestamp always return some data around 1979-81

@MichaelBaker

Are you on the APNS sandbox server or the production server? Also, can you verify that it's reading exactly 38 bytes from the socket and no fewer? If you're on the production server and the correct number of bytes are getting read then I'm not sure what the problem is.

@NicosKaralis

I'm using production APNS, and i have a small number of devices receiving pushes

using this:

while b = f.readbyte
  puts b
end

i can read 38 bytes, so i think the number of bytes are right

I have tried every solution, and still can read the feedback, everything seems normal to me

@MichaelBaker

In your example you use f. Is that the f from the old version of the code? Make sure you're reading from ssl and not sock. I had a similar problem to yours and it was because the old code reads from sock so it was reading encrypted data, where as ssl decrypts the data.

@NicosKaralis

currently i'm using: f = ssl.read(38) but this returns nothing at all.

if i change to f = sock.read(38) then i receive something, illegible, but something

@MichaelBaker

That's the problem then. You need to investigate why you can't read from the SSL connection.

@NicosKaralis

Found, thanks.

The problems was: i wasn't creating data to be displayed. The feedback connection only returns device tokens of devices that could not receive the notification because the user deleted the app.

To fix it i did this:

  1. Installed my app
  2. Send a push to the device
  3. After that remove the app
  4. Send another push (this time it won't arrive)
  5. Now the first feedback will read this token

now everything seems to work, thanks

@MichaelBaker

Cool, glad you got it figured out.

@jpoz jpoz merged commit 8c2ada4 into jpoz:master
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Aug 29, 2012
  1. @MichaelBaker

    Fixes the feedback method to read the correct number of bytes and to …

    MichaelBaker committed
    …do it from the correct socket
Showing with 18 additions and 20 deletions.
  1. +18 −20 lib/apns/core.rb
View
38 lib/apns/core.rb
@@ -8,50 +8,49 @@ module APNS
# openssl pkcs12 -in mycert.p12 -out client-cert.pem -nodes -clcerts
@pem = nil # this should be the path of the pem file not the contentes
@pass = nil
-
+
class << self
attr_accessor :host, :pem, :port, :pass
end
-
+
def self.send_notification(device_token, message)
n = APNS::Notification.new(device_token, message)
self.send_notifications([n])
end
-
+
def self.send_notifications(notifications)
sock, ssl = self.open_connection
-
+
notifications.each do |n|
ssl.write(n.packaged_notification)
end
-
+
ssl.close
sock.close
end
-
+
def self.feedback
sock, ssl = self.feedback_connection
-
+
apns_feedback = []
-
- while line = sock.gets # Read lines from the socket
- line.strip!
- f = line.unpack('N1n1H140')
- apns_feedback << [Time.at(f[0]), f[2]]
+
+ while message = ssl.read(38)
+ timestamp, token_size, token = message.unpack('N1n1H*')
+ apns_feedback << [Time.at(timestamp), token]
end
-
+
ssl.close
sock.close
-
+
return apns_feedback
end
-
+
protected
def self.open_connection
raise "The path to your pem file is not set. (APNS.pem = /path/to/cert.pem)" unless self.pem
raise "The path to your pem file does not exist!" unless File.exist?(self.pem)
-
+
context = OpenSSL::SSL::SSLContext.new
context.cert = OpenSSL::X509::Certificate.new(File.read(self.pem))
context.key = OpenSSL::PKey::RSA.new(File.read(self.pem), self.pass)
@@ -62,23 +61,22 @@ def self.open_connection
return sock, ssl
end
-
+
def self.feedback_connection
raise "The path to your pem file is not set. (APNS.pem = /path/to/cert.pem)" unless self.pem
raise "The path to your pem file does not exist!" unless File.exist?(self.pem)
-
+
context = OpenSSL::SSL::SSLContext.new
context.cert = OpenSSL::X509::Certificate.new(File.read(self.pem))
context.key = OpenSSL::PKey::RSA.new(File.read(self.pem), self.pass)
fhost = self.host.gsub('gateway','feedback')
puts fhost
-
+
sock = TCPSocket.new(fhost, 2196)
ssl = OpenSSL::SSL::SSLSocket.new(sock,context)
ssl.connect
return sock, ssl
end
-
end
Something went wrong with that request. Please try again.