5

Once I started using Channels with Phoenix, I started getting a lot of these errors on Heroku:

heroku[router]: at=error code=H15 desc="Idle connection" method=GET
path="/socket/websocket?guardian_token=eyJhbGciOiJIUz[...]&vsn=1.0.0" host=[...]
dyno=web.1 connect=0ms service=87803ms status=503 bytes=

A reliable way to reproduce this is on a laptop:

  1. Open a Phoenix page that connects to WebSockets
  2. Close the lid of your laptop
  3. Wait a minute or so (WiFi to disconnect/OS goes to sleep)
  4. The H15 error will occur.

I've set a 45s timeout on my UserChannel already; I'm running Elixir 1.4.2, Phoenix 1.2.1 and my phoenix.js was just upgraded to the one used in Phoenix 1.3.0-rc0 (link to rev)

I can see the error logged on the front-end, but after that it reconnects happily to the backend:

2017-03-04 23:28:55.351 receive: ok user:2 phx_reply (3)
2017-03-04 23:29:24.269 channel: error user:2
2017-03-04 23:29:28.713 push: user:2 phx_join (4)
2017-03-04 23:29:28.745 receive: ok user:2 phx_reply (4)

Any help or ideas how to solve this is much appreciated.

Edit: I'm familiar with Heroku's H15 error code definition so I'm looking for a fix or a workaround for getting rid of the errors (other than migrating away from Heroku, of course).

Svilen
  • 2,608
  • 24
  • 26
  • https://devcenter.heroku.com/articles/error-codes#h15-idle-connection -- This will probably answer your question. – Justin Wood Mar 05 '17 at 00:43
  • 1
    @JustinWood Thanks for the link, but it I'm looking for a fix or a workaround for this problem for my Phoenix application, rather than an explanation what the H15 error code means. – Svilen Mar 05 '17 at 10:29

1 Answers1

7

Phoenix docs recommend setting the timeout for the websocket transport to < 55 seconds:

defmodule HelloWeb.UserSocket do
  use Phoenix.Socket

  ...

  ## Transports
  transport :websocket, Phoenix.Transports.WebSocket,
    timeout: 45_000
    ...
end

Their explanation is:

This ensures that any idle connections are closed by Phoenix before they reach Heroku’s 55-second timeout window.

Peter Brown
  • 50,956
  • 18
  • 113
  • 146
  • 1
    Thanks for your answer Peter; unfortunately I already have a timeout set, and that doesn't prevent the errors from happening. – Svilen Feb 10 '18 at 17:03
  • 1
    Ah, my bad — the `timeout` param was set on the `channel`, instead of the `transport`. Putting it on the `transport`, where it should be, fixes the problem indeed! – Svilen Feb 13 '18 at 20:00