-
Notifications
You must be signed in to change notification settings - Fork 55
/
plug_websocket.ex
64 lines (53 loc) · 1.32 KB
/
plug_websocket.ex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
Mix.install([
{:plug, "~> 1.14"},
{:bandit, "~> 0.6"},
{:websock_adapter, "~> 0.5"}
])
defmodule EchoServer do
def init(_args) do
{:ok, []}
end
def handle_in({"ping", [opcode: :text]}, state) do
{:reply, :ok, {:text, "pong"}, state}
end
def terminate(:timeout, state) do
{:ok, state}
end
end
defmodule Router do
use Plug.Router
plug(Plug.Logger)
plug(:match)
plug(:dispatch)
get "/" do
conn
|> put_resp_content_type("text/html")
|> send_resp(200, """
Output: <div id="output"></div>
<script type="text/javascript">
output = document.getElementById("output")
sock = new WebSocket("ws://localhost:4000/websocket")
sock.addEventListener("message", (message) =>
output.append(message.data)
)
sock.addEventListener("open", () =>
setInterval(() => sock.send("ping"), 1000)
)
</script>
""")
end
get "/websocket" do
conn
|> WebSockAdapter.upgrade(EchoServer, [], timeout: 60_000)
|> halt()
end
match _ do
send_resp(conn, 404, "not found")
end
end
webserver = {Bandit, plug: Router, scheme: :http, options: [port: 4000]}
{:ok, _} = Supervisor.start_link([webserver], strategy: :one_for_one)
# unless running from IEx, sleep idenfinitely so we can serve requests
unless IEx.started?() do
Process.sleep(:infinity)
end