Skip to content

Instantly share code, notes, and snippets.

@efrenfuentes
Forked from alanpeabody/my_app.ex
Created May 19, 2020 15:35
Show Gist options
  • Save efrenfuentes/00b37861a0a7f29c570800e405b2e4e7 to your computer and use it in GitHub Desktop.
Save efrenfuentes/00b37861a0a7f29c570800e405b2e4e7 to your computer and use it in GitHub Desktop.
Websockets in Elixir with Cowboy and Plug
defmodule MyApp do
use Application
def start(_type, _args) do
import Supervisor.Spec, warn: false
children = [
Plug.Adapters.Cowboy.child_spec(:http, MyApp.Router, [], [
dispatch: dispatch
])
]
opts = [strategy: :one_for_one, name: Navis.Supervisor]
Supervisor.start_link(children, opts)
end
defp dispatch do
[
{:_, [
{"/ws", MyApp.SocketHandler, []},
{:_, Plug.Adapters.Cowboy.Handler, {MyApp.Router, []}}
]}
]
end
end
defmodule MyApp.Router do
use Plug.Router
plug :match
plug :dispatch
match _ do
send_resp(conn, 200, "Hello from plug")
end
end
defmodule MyApp.SocketHandler
@behaviour :cowboy_websocket_handler
def init(_, _req, _opts) do
{:upgrade, :protocol, :cowboy_websocket}
end
@timeout 60000 # terminate if no activity for one minute
#Called on websocket connection initialization.
def websocket_init(_type, req, _opts) do
state = %{}
{:ok, req, state, @timeout}
end
# Handle 'ping' messages from the browser - reply
def websocket_handle({:text, "ping"}, req, state) do
{:reply, {:text, "pong"}, req, state}
end
# Handle other messages from the browser - don't reply
def websocket_handle({:text, message}, req, state) do
IO.puts(message)
{:ok, req, state}
end
# Format and forward elixir messages to client
def websocket_info(message, req, state) do
{:reply, {:text, message}, req, state}
end
# No matter why we terminate, remove all of this pids subscriptions
def websocket_terminate(_reason, _req, _state) do
:ok
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment