pigeon icon indicating copy to clipboard operation
pigeon copied to clipboard

Timeout Error

Open io2 opened this issue 8 years ago • 14 comments

Hi there,

We are attempting to use the pigeon lib for VOIP push notification and consistently get a timeout error with Pigeon.

We have confirmed the certs are valid, it work from the dev environment. We have also confirmed the device tokens are valid, for the reason above.

The request in code looks like this

Pigeon.APNS.Notification.new("Incoming call...", deviceToken, "com.company.APP")
|> put_sound("default")
|> put_alert(%{"title" => "Incoming call..."})
|> Pigeon.APNS.push

And the timeout response is ...

{:error, :timeout,
 %Pigeon.APNS.Notification{device_token: "218b6d43ea916968939ca5eaab2eb6eaf6f730358fcd2ce8365ec88825a0b519",
  expiration: nil, id: nil,
  payload: %{"SIN" => "AwECAd1ozbA5QSSM7TXqMtyCiDtkE1kDNDU4AQ==",
    "aps" => %{"alert" => %{"title" => "Incoming call..."},
      "sound" => "default"}},
  topic: "com.company.APP"}}

and our config looks like this config/config.exs

config :pigeon,
    apns_mode: :dev,
    apns_cert: "certs/new/cert.pem",
    apns_key: "certs/new/key_unencrypted.pem",
    apns_2197: false

the certs are in a directory relative to priv/

And we have checked telnet gateway.push.apple.com 2195 && telnet gateway.push.apple.com 2196 connect without an issue

Any ideas on how to proceed or further debug this would be very helpful, specifically I cannot tell if there is a problem with the configuration and usage of pigeon as described above?

Thanks

io2 avatar May 10 '17 19:05 io2

The new APNS api uses 443 instead of the old ports, and generally timeouts occur when it's blocked in production environments. Have your tried using apns_2197: true in your config?

hpopp avatar May 11 '17 20:05 hpopp

Thanks Henry @hpopp,

I've changed to apis_2197: true and still get a timeout.

# telnet gateway.push.apple.com 2197
Trying 17.188.160.141...
Trying 17.188.164.76...
Trying 17.188.161.8...
Trying 17.188.168.16...
Trying 17.188.164.204...
Trying 17.188.167.74...
Trying 17.188.166.147...
Trying 17.188.163.72...
telnet: Unable to connect to remote host: Connection refused

---

# telnet gateway.push.apple.com 443
Trying 17.188.164.77...
Trying 17.188.167.138...
Trying 17.188.164.76...
Trying 17.188.167.16...
Trying 17.188.164.78...
Trying 17.188.166.140...
Trying 17.188.161.207...
Trying 17.188.162.202...
telnet: Unable to connect to remote host: Connection refused

both are returning connection refused

io2 avatar May 11 '17 20:05 io2

gateway is the old api. Try api.push.apple.com

hpopp avatar May 11 '17 20:05 hpopp

right, that works for telnet but still no joy on the pigeon api

{:error, :timeout,
 %Pigeon.APNS.Notification{device_token: "218b6d43ea916968939ca5eaab2eb6eaf6f730358fcd2ce8365ec88825a0b519",
  expiration: nil, id: nil,
  payload: %{"SIN" => "AwECZhbj7RzcQSKkjMctAcxPbRzRFFkDNDc2AQ==",
    "aps" => %{"alert" => %{"title" => "Incoming Call..."},
      "sound" => "default"}, "isVideo" => "1"}}}

io2 avatar May 11 '17 21:05 io2

What's the result of Kadabra.open('api.push.apple.com', :https, port: 2197)

hpopp avatar May 12 '17 14:05 hpopp

Kadabra.open('api.push.apple.com', :https, port: 2197)
{:ok, #PID<0.19397.0>}

io2 avatar May 15 '17 04:05 io2

So it looks like you can establish a connection just fine.

This is supposed to throw an error, but if you're using credentials relative to priv/ it should read

config :pigeon, :apns,
  default: %{
    mode: :prod,
    apns_cert: {:your_app, "certs/new/cert.pem"},
    apns_key: {:your_app, "certs/new/key_unencrypted.pem"},
    apns_2197: true
  }

Edit: Also realized you're using the old config style. What version of pigeon are you using?

hpopp avatar May 15 '17 14:05 hpopp

Hi Henry @hpopp , thanks for your continued help - much appreciated.

We are using pigeon 0.12.1. Also tried using the version in github directly by setting mix.exs -> {:pigeon, github: "codedge-llc/pigeon"}. We've also tried changing from kadabra to chatterbox.

When the config is updated to your suggestion above, the application fails to start with error

[error] Invalid configuration.

[info] Application pigeon exited: Pigeon.start(:normal, []) returned an error: shutdown: failed to start child: :default
    ** (EXIT) {:error, :invalid_config}

We are on Elixir 1.4.1, removing :pigeon from the applications list removes that error BUT still results in the same timeout error.

io2 avatar May 16 '17 12:05 io2

Keep :pigeon in the applications list if you are explicitly listing them-- the default worker needs to be started. Also, that error usually indicates that the paths to your cert and key are wrong.

I think the timeout response is due to the worker never getting started at all. I should probably add a specific error response for this.

hpopp avatar May 16 '17 20:05 hpopp

We suddenly experienced timeouts for all iOS push notifications via APNS. Our cause was due to a change in our build process that affected how we populate environment variables. The multi-line APNS key that we were configuring pigeon with, had escape characters that couldn't be interpreted correctly.

To summarise, a potential cause when getting timeouts could be an invalid key.

dideler avatar Feb 14 '19 18:02 dideler

Same. The solution was to replace the following in my config:

cert: "priv/certs/cert.pem" to:

cert: {:my_app, "certs/certs.pem"}

ConfigParser should probably throw an exception when a file is passed in that doesn't exist.

nkezhaya avatar Jul 12 '19 01:07 nkezhaya

Something similar here. I have two different workers configured, with everything exactly the same, e.g.

apns = [
  name1: %{
    cert: {:app, "certs/1-cert.pem"},
    key: {:app, "certs/1-key.pem"},
    mode: :prod
  },
  name2: %{
    cert: {:app, "certs/2-cert.pem"},
    key: {:app, "certs/2-key.pem"},
    mode: :prod
  }
]

config :pigeon, :apns, apns

then sending a message to via these workers, e.g.

Pigeon.APNS.push(n, to: :name1)
Pigeon.APNS.push(n, to: :name1, timeout: 100_000)
Pigeon.APNS.push(n, to: :name1, on_response: some_cb)
  1. locally - both workers do work just fine, no issues
  2. on server - name1 does work 100% of time, name2 does not work 100% of time, producing timeouts. (i.e. response: :timeout, with on_response - never answering) Order (in config) is not important, "bundle_id and cert" pair is.

So it's not the connection issue, since the other worker does work just fine.

Does anyone have any idea what's going on and how to extract more info from pigeon?

thousandsofthem avatar Jan 31 '20 21:01 thousandsofthem

@thousandsofthem My first guess would be to make sure that 2-cert.pem exists and is in the same folder as 1-cert.pem, since 1-cert.pem seems to be working.

nkezhaya avatar Jan 31 '20 22:01 nkezhaya

@whitepaperclip thanks for suggestion. Triple-checked, files are there, it took long time to notice file permissions are not correct. So essentially you're right and helped me to find out the root of the issue. Thanks again!

Just in case for anyone wondering, when removing files: non-existent cert -> response missing_provider_token non-existent key -> timeout

thousandsofthem avatar Jan 31 '20 22:01 thousandsofthem