cblavier

cblavier

Hey folks, I’m deploying a Phoenix 1.4 umbrella app with multiple web endpoints to Heroku, so I need a single endpoint that will reverse proxy my web_apps and their websockets.

The following code is working properly to dispatch plain HTTP traffic between my apps, but Cowboy crashes when loading live_reload websockets.

I wrote this code from cowboy 1.0 examples, and I guess the way I setup dispatch has changed. But I’m struggling at reading cowboy 2.5 documentation … :confused:

My proxy application :

defmodule MyProxy.Application do

  alias Plug.Cowboy

  use Application

  def start(_type, _args) do
    import Supervisor.Spec, warn: false

    port = (System.get_env("PORT") || "5000") |> String.to_integer

    cowboy = Cowboy.child_spec(
      scheme: :http,
      plug: MyProxy.Plug,
      options: [
        port: port,
        dispatch: [{:_, [
          my_app_web_live_reload(),
          my_other_app_live_reload(),
          proxy()
        ]}]
      ]
    )

    children = [cowboy]
    opts = [strategy: :one_for_one, name: MyProxy.Supervisor]
    Supervisor.start_link(children, opts)
  end

  defp my_app_web_live_reload do
    {
      "/my_app/live_reload/socket/websocket",
      Phoenix.Endpoint.CowboyWebSocket,
      {
        Phoenix.Transports.WebSocket,
        {MyApp.Endpoint, Phoenix.LiveReloader.Socket, :websocket}
      }
    }
  end

  defp my_other_app_live_reload do
    {
      "/my_other_app/live_reload/socket/websocket",
      Phoenix.Endpoint.CowboyWebSocket,
      {
        Phoenix.Transports.WebSocket,
        {MyOtherApp.Endpoint, Phoenix.LiveReloader.Socket, :websocket}
      }
    }
  end

  defp proxy do
    {:_, Cowboy.Handler, {MyProxy.Plug, []}}
  end

end

and the proxy plug:

defmodule MyProxy.Plug do

  def init(options) do
    options
  end

  def call(conn, _opts) do
    if conn.request_path =~ ~r{/my_app} do
      MyApp.Endpoint.call(conn, [])
    else
      MyOtherApp.Endpoint.call(conn, [])
    end
  end

end

The cowboy error

[error] Ranch protocol #PID<0.1043.0> of listener MyProxy.Plug.HTTP (connection #PID<0.1042.0>, stre
am id 1) terminated
** (exit) :undef
[error] :gen_event handler :error_logger_lager_h installed in :error_logger terminating
** (CaseClauseError) no case clause matching: [MyProxy.Plug.HTTP, #PID<0.1042.0>, 1, #PID<0.1043.0>,
 :undef, [{Phoenix.Endpoint.CowboyWebSocket, :init, [%{bindings: %{}, body_length: 0, cert: :undefin
ed, has_body: false, headers: %{"accept-encoding" => "gzip, deflate, br", "accept-language" => "fr-F
R,fr;q=0.9,en-US;q=0.8,en;q=0.7", "cache-control" => "no-cache", "connection" => "Upgrade" , "host" 
=> "localhost:5000", "origin" => "http://localhost:5000", "pragma" => "no-cache", "sec-websocket-ext
ensions" => "permessage-deflate; client_max_window_bits", "sec-websocket-key" => "LiihXA7p3GimivqsYH
hjqg==", "sec-websocket-version" => "13", "upgrade" => "websocket", "user-agent" => "Mozilla/5.0 (Ma
cintosh; Intel Mac OS X 10_14_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/
537.36"}, host: "localhost", host_info: :undefined, method: "GET", path: "/my_app/live_reload/socket
/websocket", path_info: :undefined, peer: {{127, 0, 0, 1}, 54652}, pid: #PID<0.1042.0>, port: 5000, 
qs: "vsn=2.0.0", ref: MyProxy.Plug.HTTP, scheme: "http", sock: {{127, 0, 0, 1}, 5000}, streamid: 1, 
version: :"HTTP/1.1"}, {Phoenix.Transports.WebSocket, {MyApp.Endpoint, Phoenix.LiveReloader.Socket, 
:websocket}}], []}, {:cowboy_handler, :execute, 2, [file: 'my_app/deps/cowboy/src/cowboy_handler.erl
', line: 41]}, {:cowboy_stream_h, :execute, 3, [file: 'my_app/deps/cowboy/src/cowboy_stream_h.erl', 
line: 293]}, {:cowboy_stream_h, :request_process, 3, [file: 'my_app/deps/cowboy/src/cowboy_stream_h.
erl', line: 271]}, {:proc_lib, :init_p_do_apply, 3, [file: 'proc_lib.erl', line: 247]}]]

Showing Posts 1 to 1

cblavier

cblavier OP

I finally figured it by myself : the Phoenix.Endpoint.CowboyWebSocket I was using is meant to be used with cowboy 1.x. For cowboy 2.x, I had to use Phoenix.Endpoint.Cowboy2Handler like this :

defp my_app_web_live_reload do
  {
    "/my_app/live_reload/socket/websocket",
    Phoenix.Endpoint.Cowboy2Handler,,
    {
      MyApp.Endpoint,
      {Phoenix.LiveReloader.Socket, :websocket}
    }
  }
end
— All posts loaded —

Where Next? Top

Trending in Questions Top

katta
I having some trouble figuring out if I have set myself too strict of standards for my production server. Currently I can handle 75% of r...
New
brecabral
Documentation While reading the Scoped Routes section, I noticed that the documentation currently refers to a problem without explainin...
New
achenet
Hello, I’m trying to build a basic Phoenix web-app, and I’d like to use Tailwind. However, when I launch mix phx.server, I get an error...
New
kpanic
Hi everyone, I am toying with the idea of building a “match maker” for giving personal help to people that wants to start coding. I sta...
New
velrest
So my question is quite simple and i have found no conclusive answer on forum, google or AI. Should we use :erlang.float for Integer to ...
New
asweet-confluent
I recently noticed that Elixir’s Logger defaults its primary log level to :debug when no :logger, :level application configuration is pre...
New
mnkhod
So i have been using ash framework for a while and i love it. However currently the issue im having with ash framework is the error handl...
New

Other Trending Topics Top

GenericJam
Edit: 2026 May 15 - This post is archived. Mob is alive!! Main docs: mob v0.7.11 — Documentation A bit of explanation for the slightly c...
New
JesseHerrick
Hey, I’m Jesse and I’m the main contributor behind Dexter, a full-featured, lightning-fast Elixir LSP optimized for large codebases. It s...
New
mudasobwa
I am happy to introduce the very α version of the new programming language compiled to BEAM. Welcome Cure. It has literally three kille...
New
garrison
Hobbes is a low-level distributed database for the Elixir programming language. Hobbes provides a simple, safe, and scalable storage lay...
New
mhanberg
Hi everyone! The first release candidate for the Expert language server project is now available! We’ve published a press release detai...
New
budgie
A little off-topic, but I feel like people here have a good head on their shoulders. I used to be quite good at making software. Was luc...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews