nomad-cli / houston Goto Github PK
View Code? Open in Web Editor NEWApple Push Notifications; No Dirigible Required
Home Page: http://nomad-cli.com
License: MIT License
Apple Push Notifications; No Dirigible Required
Home Page: http://nomad-cli.com
License: MIT License
We're evaluating houston
after inheriting a project that heavily uses grocer
.
One of the persistent problems the project had with grocer
was that failed notifications caused persistent connections to drop subsequent notifications, silently.
Pardon me if I'm retreading old ground here, but for reference, see grocer/grocer#14 for discussion around grocer
and this topic. In a nutshell, the APNS architecture notifies of failures on the push socket, but not of successes, so you're required to either block the connection until the failure notification appears, or a timeout has been exceeded. The APNS feedback service can be used to determine, after the fact, which device tokens were bad, but it will not indicate which messages have failed, so re-sending subsequent failures is complex.
It looks like the changes around e71b87d address this issue by implementing the IO.select
solution mentioned in the above issue, and implemented in a few forks (https://github.com/ping4/grocer/blob/ping4/lib/grocer/ssl_connection.rb has an example).
I'm new to IO.select
, but as far as I can tell, this;
ssl = connection.ssl
...
read_socket, write_socket = IO.select([ssl], [ssl], [ssl], nil)
will block until either read_socket
is ready for reading or write_socket
is ready for writing. So it's possible that IO.select
will return before the APNS has pushed an error code, indicating a false positive. In informal testing, this seems to be exactly what happens:
note = Houston::Notification.new(token: "8762d160 3dad3f1b ccd84855 7576bc66 784b9a61 oh who am I kidding I'm totally invalid", alert: "You'll never see me")
connection.write note.message
ssl = connection.ssl
read_socket, write_socket = IO.select([ssl], [ssl], [ssl], nil)
if read_socket && read_socket[0]
response = connection.read(6).unpack("ccN")
puts "Response: 2 #{response}"
end
The error never appears: IO.select
returned because write_socket
became ready for writing, not because read_socket became ready for reading.
Without the second argument, IO.select
will block (forever) until the read_socket
is ready with an error to read. It does, however, reliably contain error messages for failed device_tokens.
Without the second argument, and some small-ish value for timeout
(the fourth arg) accomplishes both goals, at the expense of waiting for timeout
seconds to pass before the next message can send:
read_socket, write_socket = IO.select([ssl], [], [ssl], 0.1)
The timeout tax might work in certain situations, so I'm not willing to discard it.
That said, I'm already out of my depth. My limited research indicates that this is the accepted solution area, but grocer
has mostly abandoned this idea, and nobody is happy about the blocking. Is there a solution to this that doesn't involve opening and closing connections repeatedly?
Hi @mattt
I have an issue with the gem when:
When the device is not locked, it displayed the old notification as a banner first, then the new one.
Somehow old notifications are still triggering the ringtone and the notification center to display it again... any idea what is the issue?
I made a certificate and got token. And push worked very well.
But I don't know how can I send this token to the server.
And houston, how can load this tokens? I google this but no one post it.
Please explain this. Thanks.
If I use the CLI tool with the -n flag, it isn't sending content-available in the body. Setting the content_available attribute in a ruby script works. Is anyone else seeing this?
Is the Houston::Notification::APNSError::MAXIMUM_PAYLOAD_SIZE of 2048 bytes invalid?
According to this issue, in production the maximum payload size APNS will accept is still 256 bytes.
In connection.rb, Houston::Connection.open
opens and closes a TCP connection to Apple's servers each time it is called.
However, page 47 of Apple's Local and Push Notification Programming Guide states the following:
You should also retain connections with APNs across multiple notifications. APNs may consider connections that are rapidly and repeatedly established and torn down as a denial of-service attack.
Would it be better for Houston::Connection.open
to cache connections been invocations? This approach is permitted by Apple:
You may establish multiple, parallel connections to the same gateway or to multiple gateway instances.
Preface, this may have nothing to do with Houston and a lot to do with my lack of understanding of specifying how to install gems.
My Gemfile contains this:
gem 'houston', '0.1.0', :git => 'git://github.com/mattt/houston.git'
When I deploy the app to our EC2 instance, it tries to install the gem and returns this error:
/usr/local/ruby/1.9.3/lib64/ruby/1.9.1/rubygems/installer.rb:365:in `initialize': No such file or directory - /app/www/ip2/shared/bundle/ruby/1.9.1/bundler/gems/gems/houston-0.1.0/bin/apn (Errno::ENOENT)
I find the gem installed here:
/app/www/ip2/shared/bundle/ruby/1.9.1/bundler/gems/houston-3737539fb20d/bin/apn
Whats with the weird bundler/gems/gems path and how do I make sure that the Rakefile gets the correct Houton::Version?
Looking through the sample code in the Github page, where would I enter my passphrase in the code?
apn push "<3fcdf78e 8564fcc9 91a7e5e4 3ba1e094 04c47081 9a2b7f89 f21913e5 e3864505>" -c apple_push_notification.pem -m "Hello world!" -e production
is working, with complete round trip to apns server and the device.
Push notifications successfully sent
when switching the environment:
apn push "<3fcdf78e 8564fcc9 91a7e5e4 3ba1e094 04c47081 9a2b7f89 f21913e5 e3864505>" -c apple_push_notification.pem -m "Hello world!" -e development
I still get
Push notifications successfully sent
Hi, I want have a test with Localized Formatted Strings with APNS. But it seems that I can only send string object in alert body.
How to send dictionary such like
"alert" : {
"loc-key" : "GAME_PLAY_REQUEST_FORMAT",
"loc-args" : [ "Jenna", "Frank"]
}
Thanks a lot.
For awhile, I thought Client#push
accepted an Enumerable object, so I started passing in a Set
of notifications which caused the method to silently fail. I didn't do a complete investigation, but it seems like the call to notifications.last
failed and the exception was probably eaten up by the Connection
block. While trying to get to the bottom of this, I realized the method takes a splat not an Enumerable. Was able to resolve my issue by adjusting my calling code accordingly. It's very possible this is the "right" way to do things, but what is the reasoning (for my own edification)? Also, it would be nice if the method either succeeded or didn't fail silently when passed a Set
. Maybe it's as simple as changing this:
break if notifications.count == 1 || notification == notifications.last
to
break if index == (notification.count - 1)
?
This is quite a noob question as I'm still pretty new to rails. I'm wondering where's the right place to do the basic setup for houston? i.e. if I want to send a push notification in a controller, where is the right place to set up the APN code below:
require 'houston'
APN = Houston::Client.development
APN.certificate = File.read("/path/to/apple_push_notification.pem")
Do I do it directly in that controller file? That seems wrong... Do I do it in an initializer file? Is it ok to simply just create an arbitrary file within the initializers directory? Thanks a lot!
When I send a notification like this
apn push fcc3551cd74e40d45beb109946a6ca6dc7423e16dd042e2b2aa06f07183d5b8c -c apns-dev-cert.pem -m "Credits" -d credits=100
payload's credits:
value is delivered as instance of NSString but not a NSNumber
I get the following error when I call Houston::Client.production.devices
from the rails console.
[2] pry(main)> Houston::Client.production.devices
TypeError: no implicit conversion of nil into String
from /app/vendor/bundle/ruby/2.2.0/gems/houston-2.2.3/lib/houston/connection.rb:39:in `initialize'
Just so that I don't have to enter the password every time I test a push notification. Thanks.
I copy your code and save to a pushTest.rb.It's error.uninitialized constant Houston (NameError).What can I do?Thanks!
This is not entirely Houston's fault, but the way Ruby Sockets work. When the server looses connection to Apple gateways, Houston knows nothing about it and connection#open? will still return true. Moreover, you seem to be able to write to such dead connection, yet nothing is delivered to Apple.
Underlying TCPConnection that is being opened to Apple is not working properly, yet we know nothing about it.
I have too little experience with Ruby TCP programming to solve it myself. But if someone can point me to right direction I could create a patch and pr.
Any ideas how to solve this?
Hello Mattt,
what do you think about changing the name of the device variable/parameter in the notification class to device_token? I think this would make it a bit clearer, especially in the context of using houston along with rack-push-notification. I just tripped over this, passing a device instance into the notification initializer, instead of giving it the device.token (which works, but will fail silently later on)
It's not a very big deal but imho this would make the notifications interface clearer. I know this would be a breaking change, but I think it's worth considering, because even without the rack-push-notification context this could make it more intuitive.
Cheers!
Is there a way to specify a destination url with push notification.
It would be cool if this gem had a CLI (similar to venice) that would do the .p12 -> .pem conversion for you. I have to come to the houston readme and copy the stupid command out every time I setup push notifications.
According to the following lines at the end of client.rb
's push
method:
if error
command, status, index = error.unpack("ccN")
notifications.slice!(0..index)
notifications.each(&:mark_as_unsent!)
push(*notifications)
end
it seems that the push method is called recursively until no error is returned from the APN server. Am I correct in this?
If so, isn't this a terrible idea? The APNs may respond with something as simple as "invalid token". Shouldn't there at least be a maximum retry amount?
On monday the command line binary and even the script worked like a charm. But today I run the same script and tried the same command in terminal but both failed with this error
Exception sending notification: SSL_connect returned=1 errno=0 state=SSLv3 read server session ticket A:
sslv3 alert certificate revoked
Is this problem on my side or not?
I am looking to build a logging system for APNs errors that houston may receive when sending notifications.
For example, in the Apple documentation table 5.1 useful response error codes are listed that can be helpful when debugging issues when a connection is established but the notification is malformed in some way.
The node-apn library, for example, defines these error codes and allows clients to attach callbacks to an event emitter so that errors can be logged (or otherwise responded to in some way).
Does such a thing exist in houston? I've looked through the source but it seems that clients may not have a facility to monitor the lower level feedback that houston gets from the APNs socket connection.
Thanks for any advice you might have!
The apn command line reports success even if the token is invalid, say, due to missing characters (easily reproducible by deleting the last character from a token).
When I try to send a notification I'm seeing the following error:
Errno::EPIPE (Broken pipe)
I don't get a good stack trace, but through some logging I've managed to find that it's happening in Client#push
in the loop that actually calls Connection#write
. It does get through a few notifications (devices) before dying, usually somewhere between 20-50 out of 116. Even in the iteration where the exception occurs, Connection#open?
still returns true. I don't know Ruby sockets very well, so I'm not sure where to go from here.
Once you have the certificate from Apple for your application, export your key and the apple certificate as p12 files.
Should it be the public key or private key?
Apple recently announce that it is dropping support for SSLv3. Does this gem use at least TLS 1.0?
I can't get Houston to work in my Rails app.
I initialize it in a houston.rb file in /config/initializers/ with the below code:
APN = Houston::Client.production
APN.certificate = File.read("config/apple_push_notification_production.pem")
After that I use it as shown in the docs:
notification = Houston::Notification.new(device: token)
notification.alert = "Hello, World!"
APN.push(notification)
The gem seems properly initialized as typing APN in the Rails console outputs data like @gateway_uri @certificate etc..
Using the command line tool, the same token, and the same key everything works just fine. What could be the issue?
It should probably warn you if the message is too long, as this will cause it to be silently clipped off by apple and thus invalid json.
I cannot send some emojis.
☕ (\xE2\x98\x95), ☝️ (\xE2\x98\x9D) are fine but 🎮 (\xF0\x9F\x8E\xAE), 🍕 (\xF0\x9F\x8D\x95) are broken.
I struggled with this issue for a long time, and finally discovered what was happening. I'm using version 2.2.1 of the gem.
I found that I could send notifications via the command line apn
tool, but it was failing to send when integrating Houston into my code. After trying all sorts of different combinations I cut the code down until it was as simple as this:
apn = Houston::Client.development
apn.certificate = File.read("/path/to/apple_push_notification.pem")
token = "<ce8be627 2e43e855 16033e24 b4c28922 0eeda487 9c477160 b2545e95 b68b5969>"
notification = Houston::Notification.new(device: token)
notification.alert = "Hello, World!"
apn.push(notification)
I.e., just set a message and send. The notification would never arrive, and there was no error in notification.error
. As a last attempt, I tried the Silent Notifications code in the README, meaning that I created a Notification with Houston::Notification.new(token: token, sound: '')
, and it finally sent!
It seems like there's an issue with the default sound option. Maybe setting it to blank is the safest default?
Actually, I discovered in the end that it was down to invalid tokens in the database. I had registered some tokens from the iOS simulator, and in my Houston code (using the persistent connection format) was looping through all the devices sending out notifications, e.g.:
Device.each do |device|
notification = Houston::Notification.new(device: device.token)
notification.alert = "Hello, world"
connection.write(notification.message)
end
It seems that all notifications sent after the one to the simulator would never arrive. After deleting the offending tokens from the database, the notifications would go through.
Is this an issue with the APN service? It seems like a bit of an issue though, as invalid tokens bring the whole thing to a halt. I don't know if you have any thoughts on this?
Thanks
This merge pull request #32 for silent push broke the test suite. See the comment at the bottom of the pull request for a possible resolve.
EDIT: Using Houston::Client.production has no affect. puts notification.error prints out nothing.
Following tutorial, nothing useful is logged or returned. My pushes aren't arriving.
I've tried removing spaces and <> too.
Using rspec 3.1.0
Using simplecov-html 0.8.0
require 'houston'
# Environment variables are automatically read, or can be overridden by any specified options. You can also
# conveniently use `Houston::Client.development` or `Houston::Client.production`.
APN = Houston::Client.development
APN.certificate = File.read("/Users/quantum/Documents/cliqupprodcerts.pem")
# An example of the token sent back when a device registers for notifications
token = "tokentoken"
# Create a notification that alerts a message to the user, plays a sound, and sets the badge on the app
notification = Houston::Notification.new(device: token)
notification.alert = "Hello, World!"
# Notifications can also change the badge count, have a custom sound, have a category identifier, indicate available Newsstand content, or pass along arbitrary data.
notification.badge = 57
notification.sound = "sosumi.aiff"
notification.category = "INVITE_CATEGORY"
notification.content_available = true
notification.custom_data = {foo: "bar"}
# And... sent! That's all it takes.
v = APN.push(notification)
puts v
~
This might be an issue of better documentation, but as a first time user of houston and push notifications, I had the following problem:
I used dotenv to set the environment variable:
APN_CERTIFICATE='/Users/mehulkar/dev/myproj/api/cert.pem'
in an Rails initializer, I create the client, assuming that the env vars will be used automatically.
APN = Houston::Client.new
Now, when I open up rails console and try to send a push, I get this error.
notification = Houston::Notification.new(token: 'foo')
APN.push(notification)
#=> OpenSSL::PKey::RSAError: Neither PUB key nor PRIV key: not enough data
Looking at the code, this seems obvious to me because Houston::Client.development
, for example, sets the certificate
accessor to the contents of the file, rather than the path
When I reassign APN.certificate=File.read(APN.certificate)
, then it works.
There are a few of solutions:
certificate_path
and on initialize, attempt to read that if @certificate
is nil
APN.certificate
if FIle.exists? APN.certificate
is true
either in Client#push
or in Client#new
Let me know if I've missed something obvious or if I'm completely wrong here.
I'm ready for my code to switch from the Sandbox APN server to the production server. I generated a production certificate and can successfully connect to the APN server with it. However when I try to manually send a notification it never arrives on the device, even though Houston is telling me that it was pushed.
I open my app in the release scheme and grab the APN token given to me by apple. I convert it into a NSString. Then, using the certificate I generated and tested, I run this command:
apn push "<apnstoken>" -c ck.pem -m "THIS BETTER WORK" -p
I type in my password and I see: 1 push notification sent successfully
but I never actually see any notification on my device. This happens both with the CLI, and in code using the ruby gem:
apn = Houston::Client.production
apn.certificate = File.read("<pathtocert>")
apn.passphrase = '<password>'
# Create a notification that alerts a message to the user, plays a sound, and sets the badge on the app
notification = Houston::Notification.new(device: apntoken)
notification.alert = body
notification.custom_data = options
# Notifications can also change the badge count, have a custom sound, have a category identifier, indicate available Newsstand content, or pass along arbitrary data.
notification.content_available = true
# And... sent! That's all it takes.
apn.push(notification)
I'm used the same process for creating the cert as I did with the sandbox -- except I chose Production cert and not development.
And the code I'm using is the same with the updated password and change to Client.production
.
The notification arrive on my device
A successful response, but no notification
ruby 2.0.0p353 (2013-11-22) [x86_64-linux]
Linux 3.10.0-123.8.1.el7.x86_64 #1 SMP Mon Sep 22 19:06:58 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux
(CentOS 7)In case we send a certain amount of push notifications, they don’t seem to be delivered correctly. Everything works correctly for a lower amount of push notifications. We do not use persistent connections.
Here’s some very rough logging code that we had in place:
client.push(*notifications)
Rails.logger.info "PNS Job (1/2): Send #{notifications.length} notifications. Notification Sample: #{notifications.first.inspect}. Errors: #{notifications.collect(&:error).compact}. Sent: #{notifications.collect(&:sent?)}"
Rails.logger.info "PNS Job (2/2): #{client.devices}, Push Infos: #{push_options.inspect}"
All following examples were created with the production build of the app, using the production certificate and Houston production client with houston 2.2.1.
Here’s the log output of a working example. As you can see, the errors are empty and both notifications are reported as being sent, and they are correctly received on both clients.
PNS Job (1/2): Send 2 notifications. Notification Sample: #<Houston::Notification:0x000000070bb240 @token="<REPLACED>", @alert="Some Text", @badge=1, @sound=nil, @category=nil, @expiry=nil, @id=0, @priority=nil, @content_available=true, @custom_data={:custom_data=>{:rscs=>[{REPLACED}]}}, @sent_at=2014-09-26 10:15:13 +0200>.
Errors: []. Sent: [true, true]
PNS Job (2/2): [], Push Infos: {:alert=>"Some Text", :badge=>1, :content_available=>true, :custom_data=>{:rscs=>[{REPLACED}]}}
Here’s the log output of an example that does not work. Again, the errors are empty and all notifications are reported as being sent, but they are not in fact received on the target devices. The target devices include the two devices from the previous working example:
PNS Job (1/2): Send 23 notifications. Notification Sample: #<Houston::Notification:0x0000000c8dc488 @token="<REPLACED>", @alert="Some Alert", @badge=1, @sound=nil, @category=nil, @expiry=nil, @id=0, @priority=nil, @content_available=true, @custom_data={:custom_data=>{:rscs=>[{REPLACED}]}}, @sent_at=2014-09-29 15:33:36 +0200>.
Errors: []. Sent: [true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true]
PNS Job (2/2): [], Push Infos: {:alert=>"Some Alert", :badge=>1, :content_available=>true, :custom_data=>{:rscs=>[{REPLACED}]}}
What could be the source of the error or what else could we look into to narrow down the problem?
I've fixed this issue, but I reckon it might be good to leave a note of it here:
I was getting silent failures when sending push notifications -- the notification
object, after calling push()
, had no errors on it, but nothing was being sent out. After a bit of digging, I noticed that it was because I had the client set as Houston::Client.production
(to match the Rails environment), where the certificate file was not for a production environment. Switching over to Houston::Client.development
fixed the problem.
I know this isn't Houston's issue, per se, but I did notice that folks were having problems with silent failures. This might be a lead for some of you. I don't even know if it's possible for Houston to look at the certificate and determine its proper environment, then alert me of a mismatch, but I hope this helps people in the interim.
If i want to send more than one messages is the expected call supposed to be this?
apn_client.push(message1,message2,message3)
I would expect it would be more natural to call
apn_client.push(messages_array)
The method inside should be able to handle one or many messages.
At the moment i have to call it as
apn_client.push(*message_array)
What do you think?
I initially thought that the CLI automatically picked development or production push servers depending on the information in the .pem file. This would be great since it's such an easy mistake to make when testing production certificates. The CLI even responded successfully when using a production SSL certificate on the development servers.
When you create an APNs certificate, you usually add it to the Keychain. Keychain only supports exporting to PKCS#12 format, which makes it necessary to convert the certificate to .PEM format using OpenSSL. This is an annoying step and according to OpenSSL::PKCS12 Ruby already supports PKCS12 certificates. This could be added to get rid of the conversion step.
In addition, through using Security tool we could also support the certificates in Keychain.
It would be nice to have houston test its own internals.
When running my own tests, it would be even better would be to add a push notifications to an internal deliveries queue. That way, as an app developer, I do not need to stub calls to Houston, to prevent a connection to Apple services.
I think ActionMailer::Base.deliveries
is a good example of how one could implement this.
If Houston is initialized without a passphrase, e.g.:
APN = Houston::Client.development
APN.certificate = File.read("#{Rails.root}/config/aps_development.pem")
Then the call to
Houston::Client.development.devices
fails in connection.rb:39, because @passphrase
is nil.
Hi there!
I've been using Houston for awhile and it is awesome for sending out APNS. My rails server is currently on Heroku and I am sending notifications via Houston in the background with Sidekiq. The problem is every hour, I get SSL failure and no more notifications can be fired. What I'm seeing in the logs looks like:
2014-04-09T18:31:03.254876+00:00 app[worker.1]: 2014-04-09T18:31:03Z 2 TID-ov652jh60 NotificationWorker JID-6e547188b78402ed2702f70d INFO: fail: 0.009 sec
2014-04-09T18:31:03.261789+00:00 app[worker.1]: 2014-04-09T18:31:03Z 2 TID-ov652jh60 WARN: {"retry"=>true, "queue"=>"default", "unique"=>true, "class"=>"NotificationWorker", "args"=>[561, "a0233ebdda747002e2b71113bf26adcd8a9188005113c24a4b50ad3098044a41"], "jid"=>"6e547188b78402ed2702f70d", "enqueued_at"=>1397066881.4699736, "error_message"=>"SSL_write: bad write retry", "error_class"=>"OpenSSL::SSL::SSLError", "failed_at"=>1397066881.4908812, "retry_count"=>6, "retried_at"=>1397068263.2529194}
2014-04-09T18:31:03.261843+00:00 app[worker.1]: 2014-04-09T18:31:03Z 2 TID-ov652jh60 WARN: SSL_write: bad write retry
2014-04-09T18:31:03.261929+00:00 app[worker.1]: 2014-04-09T18:31:03Z 2 TID-ov652jh60 WARN: /app/vendor/ruby-2.1.1/lib/ruby/2.1.0/openssl/buffering.rb:326:in `syswrite'
2014-04-09T18:31:03.261929+00:00 app[worker.1]: /app/vendor/ruby-2.1.1/lib/ruby/2.1.0/openssl/buffering.rb:326:in `do_write'
2014-04-09T18:31:03.261929+00:00 app[worker.1]: /app/vendor/ruby-2.1.1/lib/ruby/2.1.0/openssl/buffering.rb:344:in `write'
2014-04-09T18:31:03.261929+00:00 app[worker.1]: /app/app/wo
rkers/notification_worker.rb:43:in `block in perform'
2014-04-09T18:31:03.261929+00:00 app[worker.1]: /app/vendor/bundle/ruby/2.1.0/gems/connection_pool-2.0.0/lib/connection_pool.rb:58:in `with'
2014-04-09T18:31:03.261929+00:00 app[worker.1]: /app/app/workers/notification_worker.rb:27:in `perform'
2014-04-09T18:31:03.261929+00:00 app[worker.1]: /app/vendor/bundle/ruby/2.1.0/gems/sidekiq-3.0.0/lib/sidekiq/processor.rb:50:in `block (2 levels) in process'
2014-04-09T18:31:03.261929+00:00 app[worker.1]: /app/vendor/bundle/ruby/2.1.0/gems/sidekiq-3.0.0/lib/sidekiq/middleware/chain.rb:122:in `call'
2014-04-09T18:31:03.261929+00:00 app[worker.1]: /app/vendor/bundle/ruby/2.1.0/gems/sidekiq-3.0.0/lib/sidekiq/middleware/chain.rb:122:in `block in invoke'
2014-04-09T18:31:03.261929+00:00 app[worker.1]: /app/vendor/bundle/ruby/2.1.0/gems/newrelic_rpm-3.7.3.204/lib/new_relic/agent/instrumentation/sidekiq.rb:30:in `block in call'
2014-04-09T18:31:03.262153+00:00 app[worker.1]: /app/vendor/bundle/ruby/2.1.0/gems/newrelic_rpm-3.7.3.204/lib/new_relic/agent/instrumentation/controller_instrumentation.rb:335:in `perform_action_with_newrelic_trace'
2014-04-09T18:31:03.262153+00:00 app[worker.1]: /app/vendor/bundle/ruby/2.1.0/gems/newrelic_rpm-3.7.3.204/lib/new_relic/agent/instrumentation/sidekiq.rb:21:in `call'
2014-04-09T18:31:03.262153+00:00 app[worker.1]: /app/vendor/bundle/ruby/2.1.0/gems/sidekiq-3.0.0/lib/sidekiq/middleware/chain.rb:124:in `block in invoke'
2014-04-09T18:31:03.262153+00:00 app[worker.1]: /app/vendor/bundle/ruby/2.1.0/gems/sidekiq-3.0.0/lib/sidekiq/middleware/server/active_record.rb:6:in `call'
2014-04-09T18:31:03.262153+00:00 app[worker.1]: /app/vendor/bundle/ruby/2.1.0/gems/sidekiq-3.0.0/lib/sidekiq/middleware/chain.rb:124:in `block in invoke'
2014-04-09T18:31:03.262153+00:00 app[worker.1]: /app/vendor/bundle/ruby/2.1.0/gems/sidekiq-3.0.0/lib/sidekiq/middleware/server/retry_jobs.rb:62:in `call'
2014-04-09T18:31:03.262153+00:00 app[worker.1]: /app/vendor/bundle/ruby/2.1.0/gems/sidekiq-3.0.0/lib/sidekiq/middleware/chain.rb:124:in `block in invoke'
2014-04-09T18:31:03.262153+00:00 app[worker.1]: /app/vendor/bundle/ruby/2.1.0/gems/sidekiq-3.0.0/lib/sidekiq/middleware/server/logging.rb:11:in `block in call'
2014-04-09T18:31:03.262153+00:00 app[worker.1]: /app/vendor/bundle/ruby/2.1.0/gems/sidekiq-3.0.0/lib/sidekiq/logging.rb:22:in `with_context'
2014-04-09T18:31:03.262153+00:00 app[worker.1]: /app/vendor/bundle/ruby/2.1.0/gems/sidekiq-3.0.0/lib/sidekiq/middleware/server/logging.rb:7:in `call'
2014-04-09T18:31:03.262354+00:00 app[worker.1]: /app/vendor/bundle/ruby/2.1.0/gems/sidekiq-3.0.0/lib/sidekiq/middleware/chain.rb:124:in `block in invoke'
2014-04-09T18:31:03.262354+00:00 app[worker.1]: /app/vendor/bundle/ruby/2.1.0/gems/sidekiq-3.0.0/lib/sidekiq/middleware/chain.rb:127:in `call'
2014-04-09T18:31:03.262354+00:00 app[worker.1]: /app/vendor/bundle/ruby/2.1.0/gems/sidekiq-3.0.0/lib/sidekiq/middleware/chain.rb:127:in `invoke'
2014-04-09T18:31:03.262354+00:00 app[worker.1]: /app/vendor/bundle/ruby/2.1.0/gems/sidekiq-3.0.0/lib/sidekiq/processor.rb:49:in `block in process'
2014-04-09T18:31:03.262354+00:00 app[worker.1]: /app/vendor/bundle/ruby/2.1.0/gems/sidekiq-3.0.0/lib/sidekiq/processor.rb:92:in `stats'
2014-04-09T18:31:03.262354+00:00 app[worker.1]: /app/vendor/bundle/ruby/2.1.0/gems/sidekiq-3.0.0/lib/sidekiq/processor.rb:48:in `process'
2014-04-09T18:31:03.262354+00:00 app[worker.1]: /app/vendor/bundle/ruby/2.1.0/gems/celluloid-0.15.2/lib/celluloid/calls.rb:25:in `public_send'
2014-04-09T18:31:03.262354+00:00 app[worker.1]: /app/vendor/bundle/ruby/2.1.0/gems/celluloid-0.15.2/lib/celluloid/calls.rb:25:in `dispatch'
2014-04-09T18:31:03.262354+00:00 app[worker.1]: /app/vendor/bundle/ruby/2.1.0/gems/celluloid-0.15.2/lib/celluloid/calls.rb:122:in `dispatch'
2014-04-09T18:31:03.262354+00:00 app[worker.1]: /app/vendor/bundle/ruby/2.1.0/gems/celluloid-0.15.2/lib/celluloid/actor.rb:322:in `block in handle_message'
2014-04-09T18:31:03.262922+00:00 app[worker.1]: /app/vendor/bundle/ruby/2.1.0/gems/celluloid-0.15.2/lib/celluloid/actor.rb:416:in `block in task'
2014-04-09T18:31:03.262922+00:00 app[worker.1]: /app/vendor/bundle/ruby/2.1.0/gems/celluloid-0.15.2/lib/celluloid/tasks.rb:55:in `block in initialize'
2014-04-09T18:31:03.262922+00:00 app[worker.1]: /app/vendor/bundle/ruby/2.1.0/gems/celluloid-0.15.2/lib/celluloid/tasks/task_fiber.rb:13:in `block in create'
My NotificationWorker file looks like
class NotificationWorker
include Sidekiq::Worker
sidekiq_options unique: true
require 'houston'
APN_POOL = ConnectionPool.new(:size => 2, :timeout => 300) do
uri, certificate = if Rails.env.development?
[
Houston::APPLE_DEVELOPMENT_GATEWAY_URI,
File.read(ENV["APN_CERT"])
]
else
[
Houston::APPLE_PRODUCTION_GATEWAY_URI,
File.read(ENV["APN_CERT"])
]
end
connection = Houston::Connection.new(uri, certificate, "password")
connection.open
connection
end
def perform(notification_id, token)
APN_POOL.with do |connection|
notification = Notification.find(notification_id)
remote_notification = Houston::Notification.new(device: token)
remote_notification.alert = notification.body
remote_notification.badge = 1
connection.write(remote_notification.message)
end
end
end
My Procfile looks like:
worker: bundle exec sidekiq
I have other workers running but I've limited the problem down to this notification_worker class. Has anyone else run into this problem before also?
Thanks a lot!
Anderthan
Houston currently allows a timeout to be set when communicating over an existing connection (and even sets a default 👍 ), but it is not possible to specify a timeout for opening that connection. This seems to be more complicated to implement with TCPSocket
, but would be a very valuable addition!
It is incorrect to use < token > string in the Houston API because this is just a string representation of NSData used for debugging. The correct token should look like a simple hex string with no spaces or angle brackets. This is how it is stored in pretty much every implementation. The way Houston does it makes the API very awkward and inconvenient.
The version of this gem on rubygems is 0.3.1, but that version is missing from this repository. It is possibly just a matter of the tag not being pushed.
firstly, thanks for ur efforts
when i send push notification to ios device through my local server it is work well, but when i push from production server nothing is send ?
using houston (2.2.1) ruby 2.1.2 and rails 4.1.4 i m sending push notification to the users but even tho i entered false device token it doesn't raise any notification error, and overtime when i try to use Feedback service it gives me an empty array.
notification = Houston::Notification.new(device: User.last.device_token)
notification.alert = "Feedback test!"
connection.write(notification.message)
puts "Error: #{notification.error}." if notification.error
is it some kind of bug anything wrong in my side,
I can send the other notifications without a problem but i need to know if its not sent and the reason (the 10 feedback code of apple provides)
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.