cblavier
Cowboy 2.5 reverse proxy with websockets
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 … ![]()
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]}]]
Marked As Solved
cblavier
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
2
Popular in Questions
I am constructing a JSON object (map) and I need to conditionally set a field. I’m trying to write proper elixir-way code… and I’m at a l...
New
Hi,
I have to write a raw query for one of my project. But till now I have used ecto queries and don’t have much experience writing raw ...
New
Hello, I get Persian date from my client and convert it to normal calendar like this:
def jalali_string_to_miladi_english_number(persi...
New
I have a server on AWS, and was running a load test using artillery. When looking at the Phoenix dashboard I see the Ports going to 100% ...
New
Hi all,
Trying to get some more clarity over utc_datetime and naive_datetime for Ecto:
The documentation above suggests that while ...
New
I tried installing
elixir 1.11.2
erlang 23.3.4
via asdf in my zsh shell. Enabled the versions locally and globally.
When I list them ...
New
Hi guys, i’m new in the Elixir world, and i have to say, that i love it!
i’m having some problem to understand anonymous functions with ...
New
i’m a new one to elixir
which editor can i use
vs code? or atom?
Thanks! :smiley:
New
I have a super simple question about elixir - how would I take a file like this
foo
bar
baz
and output a new file that enumerates th...
New
Currently suffering from paralysis by [HTTP client] analysis. This is rather unusual in Elixirland as there tends to be consensus on the ...
New
Other popular topics
I have a another noob question about loop. Since elixir is immutable, while loop is not directly possible.
total = 10
while total != 0
...
New
I believe there are people here who are dealing with CSV files import on the daily basis, and since Excel is a really popular tool there ...
New
What’s the safe way to decode a JSON string into a struct? I want to avoid calling String.to_atom. Jason.decode can give me a map with st...
New
Hello guys,
I have finally made it. I created an admin interface for a framework. It’s been on my todo list for years and with the curre...
New
Hello, how can I check the Phoenix version ?
Thanks !
New
I have a relationship of love and hate with Elixir. Lots of things are just absolutely right, but there are some things that are kind of ...
New
Using vs code and installed ElixirLS: support and debugger.
And I got an error popped up on start up says
Failed to run ‘elixir’ comma...
New
Original source of discussion: This topic on the Pragmatic Programmers’ Functional Web Development with Elixir, OTP, and Phoenix forum.
...
New
Hello everyone,
Long time lurker first time poster here. I’ve recently begun working on Elixir full-time again! :raised_hands: It’s been...
New
Hi. I’ve noticed that Windows Powershell has it’s own IEX command and you cannot access Elixir’s IEX due to the conflict. This isn’t a cr...
New








