Skip to content

Commit

Permalink
update chat app example to HTTP2
Browse files Browse the repository at this point in the history
  • Loading branch information
CrowdHailer committed Aug 22, 2017
1 parent 200a6fb commit ab2446a
Show file tree
Hide file tree
Showing 6 changed files with 80 additions and 68 deletions.
4 changes: 2 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
FROM elixir:1.4.4
FROM elixir:1.5.1

# Important! Update this no-op ENV variable when this Dockerfile
# is updated with the current date. It will force refresh of all
# of the base images and things like `apt-get update` won't be using
# old cached versions when the Dockerfile is built.
ENV REFRESHED_AT=2017-06-02
ENV REFRESHED_AT=2017-08-22

RUN apt-get update && apt-get install -y inotify-tools

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ for i in `docker ps -q`; do echo $i; echo " : "; docker inspect $i | grep -i ipa


```
docker run web mix test
docker-compose run web mix test
```

## TODO
Expand Down
9 changes: 6 additions & 3 deletions lib/water_cooler/application.ex
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,13 @@ defmodule WaterCooler.Application do
certificate_key: certificate_key_path()
]

options = [port: secure_port(), certfile: certificate_path, keyfile: certificate_key_path()]

children = [
worker(WaterCooler.WWW, [[port: port()]], id: :http),
worker(WaterCooler.WWW, [[port: secure_port(), tls: tls_options]], id: :https),
worker(WaterCooler.DNSDiscovery, [System.get_env("SERVICE_NAME")])
# worker(WaterCooler.WWW, [[port: port()]], id: :http),
# worker(WaterCooler.WWW, [[port: secure_port(), tls: tls_options]], id: :https),
supervisor(Ace.HTTP2.Service, [{WaterCooler.WWW, []}, options]),
worker(WaterCooler.DNSDiscovery, [System.get_env("SERVICE_NAME"), options])
]

opts = [strategy: :one_for_one, name: WaterCooler.Supervisor]
Expand Down
71 changes: 44 additions & 27 deletions lib/water_cooler/www.ex
Original file line number Diff line number Diff line change
@@ -1,41 +1,58 @@
defmodule WaterCooler.WWW do
use GenServer

use Tokumei
alias WaterCooler.ChatRoom
require ChatRoom
require ChatRoom

require EEx

@route_name :home
route [], request do
:GET ->
Response.ok(render("home_page.html", %{}))
:POST ->
{:ok, %{message: message}} = parse_publish_form(request.body)
{:ok, _} = ChatRoom.publish(message)
Helpers.redirect("/")
EEx.function_from_file(:defp, :home_page, Path.join(__DIR__, "./templates/home_page.html.eex"), [])
EEx.function_from_file(:defp, :not_found, Path.join(__DIR__, "./templates/not_found.html.eex"), [])

def start_link() do
GenServer.start_link(__MODULE__, :ready)
end

@route_name :updates
route ["updates"] do
:GET ->
{:ok, _} = ChatRoom.join()
%Ace.ChunkedResponse{
status: 200,
headers: [
{"cache-control", "no-cache"},
{"transfer-encoding", "chunked"},
{"connection", "keep-alive"},
{"content-type", "text/event-stream"}
]
}
def handle_info({stream, request}, :ready) do
case {request.method, request.path} do
{"GET", "/"} ->
body = home_page()
response = Ace.Response.new(200, [], body)
Ace.HTTP2.Server.send_response(stream, response)
{:noreply, :done}
{"GET", "/updates"} ->
{:ok, _} = ChatRoom.join()
response = Ace.Response.new(200, [{"content-type", "text/event-stream"}], true)
Ace.HTTP2.Server.send_response(stream, response)
{:noreply, {:updates, stream}}
{"POST", "/"} ->
true = request.body
{:noreply, :reading}
{"GET", _} ->
body = not_found()
response = Ace.Response.new(404, [], body)
Ace.HTTP2.Server.send_response(stream, response)
{:noreply, :done}
end
end

def handle_info(ChatRoom.post(data), _) do
data = ServerSentEvent.serialize(%ServerSentEvent{lines: [data], type: "chat"})
[data]
def handle_info({stream, %{data: body, end_stream: true}}, :reading) do
{:ok, %{message: message}} = parse_publish_form(body)
{:ok, _} = ChatRoom.publish(message)

response = Ace.Response.new(303, [{"location", "/"}], false)
Ace.HTTP2.Server.send_response(stream, response)
{:stop, :normal, :reading}
end

error %NotFoundError{} do
Raxx.Response.not_found(render("not_found.html", %{}))
def handle_info(ChatRoom.post(data), {:updates, stream}) do
data = ServerSentEvent.serialize(%ServerSentEvent{lines: [data], type: "chat"})
Ace.HTTP2.Server.send_data(stream, data)
{:noreply, {:updates, stream}}
end
def handle_info({stream, {:reset, :cancel}}, {:updates, stream}) do
{:stop, :normal, {:updates, stream}}
end

def parse_publish_form(raw) do
Expand Down
10 changes: 4 additions & 6 deletions mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,10 @@ defmodule WaterCooler.Mixfile do

defp deps do
[
{:tokumei, "~> 0.6.3"},
{:ace_http, "~> 0.4.0"},
{:server_sent_event, "~> 0.1.0"},
{:mix_docker, "~> 0.4.2"},
{:exsync, "~> 0.1.4"},
{:wobserver, "~> 0.1.7"}
{:ace, "~> 0.12.1"},
{:server_sent_event, "~> 0.2.0"},
{:exsync, "~> 0.2.0"},
{:wobserver, "~> 0.1.8"}
]
end
end
52 changes: 23 additions & 29 deletions mix.lock
Original file line number Diff line number Diff line change
@@ -1,29 +1,23 @@
%{"ace": {:hex, :ace, "0.9.0", "c7255dea811db3ec8b4d461c852f746896de800aba94d3a3afaa0e165edc34e7", [:mix], [], "hexpm"},
"ace_http": {:hex, :ace_http, "0.4.5", "3227ec8407f7eecbeeb9026b854c07b28c4f6b2f9617d99d1997788a8c962b46", [:mix], [{:ace, "~> 0.9.0", [hex: :ace, repo: "hexpm", optional: false]}, {:http_status, "~> 0.2.0", [hex: :http_status, repo: "hexpm", optional: false]}, {:raxx, "~> 0.11.1", [hex: :raxx, repo: "hexpm", optional: false]}], "hexpm"},
"certifi": {:hex, :certifi, "1.2.1", "c3904f192bd5284e5b13f20db3ceac9626e14eeacfbb492e19583cf0e37b22be", [:rebar3], [], "hexpm"},
"cowboy": {:hex, :cowboy, "1.1.2", "61ac29ea970389a88eca5a65601460162d370a70018afe6f949a29dca91f3bb0", [:rebar3], [{:cowlib, "~> 1.0.2", [hex: :cowlib, repo: "hexpm", optional: false]}, {:ranch, "~> 1.3.2", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm"},
"cowlib": {:hex, :cowlib, "1.0.2", "9d769a1d062c9c3ac753096f868ca121e2730b9a377de23dec0f7e08b1df84ee", [:make], [], "hexpm"},
"distillery": {:hex, :distillery, "1.4.0", "d633cd322c8efa0428082b00b7f902daf8caa166d45f9022bbc19a896d2e1e56", [:mix], [], "hexpm"},
"exfswatch": {:hex, :exfswatch, "0.4.2", "d88a63b5c2f8f040230d22010588ff73286fd1aef32564115afa3051eaa4391d", [:mix], [], "hexpm"},
"exsync": {:hex, :exsync, "0.1.4", "f5800f5c3137271bf7c0f5ca623919434f91798e1be1b9d50fc2c59168d44f17", [:mix], [{:exfswatch, "~> 0.4", [hex: :exfswatch, repo: "hexpm", optional: false]}], "hexpm"},
"gproc": {:hex, :gproc, "0.3.1", "ec14f40cb941bde3f940de59c11e59beb2977e90dbae72fab3ddf77743fd4ea9", [:rebar], [], "hexpm"},
"hackney": {:hex, :hackney, "1.8.6", "21a725db3569b3fb11a6af17d5c5f654052ce9624219f1317e8639183de4a423", [:rebar3], [{:certifi, "1.2.1", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "5.0.2", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "1.0.1", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "1.0.2", [hex: :mimerl, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "1.1.1", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm"},
"http_status": {:hex, :http_status, "0.2.1", "74fa942b5874966a25088162e5297ad52dd5e6a29b88ad4a73953aa55e58e3bb", [:mix], [], "hexpm"},
"httpoison": {:hex, :httpoison, "0.11.2", "9e59f17a473ef6948f63c51db07320477bad8ba88cf1df60a3eee01150306665", [:mix], [{:hackney, "~> 1.8.0", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm"},
"idna": {:hex, :idna, "5.0.2", "ac203208ada855d95dc591a764b6e87259cb0e2a364218f215ad662daa8cd6b4", [:rebar3], [{:unicode_util_compat, "0.2.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm"},
"metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm"},
"mime": {:hex, :mime, "1.1.0", "01c1d6f4083d8aa5c7b8c246ade95139620ef8effb009edde934e0ec3b28090a", [:mix], [], "hexpm"},
"mimerl": {:hex, :mimerl, "1.0.2", "993f9b0e084083405ed8252b99460c4f0563e41729ab42d9074fd5e52439be88", [:rebar3], [], "hexpm"},
"mix_docker": {:hex, :mix_docker, "0.4.2", "366b99bf6091155f40d408db5d8509a8760fd669442eeacdcf8444effc9f04d6", [:mix], [{:distillery, "~> 1.2", [hex: :distillery, repo: "hexpm", optional: false]}], "hexpm"},
"plug": {:hex, :plug, "1.3.5", "7503bfcd7091df2a9761ef8cecea666d1f2cc454cbbaf0afa0b6e259203b7031", [:mix], [{:cowboy, "~> 1.0.1 or ~> 1.1", [hex: :cowboy, repo: "hexpm", optional: true]}, {:mime, "~> 1.0", [hex: :mime, repo: "hexpm", optional: false]}], "hexpm"},
"poison": {:hex, :poison, "3.1.0", "d9eb636610e096f86f25d9a46f35a9facac35609a7591b3be3326e99a0484665", [:mix], [], "hexpm"},
"ranch": {:hex, :ranch, "1.3.2", "e4965a144dc9fbe70e5c077c65e73c57165416a901bd02ea899cfd95aa890986", [:rebar3], [], "hexpm"},
"raxx": {:hex, :raxx, "0.11.1", "9e2e8955fae9ecd33dc0a6d9cd50d083b209f3c859c548db0197ce39b9247146", [:mix], [{:http_status, "~> 0.2", [hex: :http_status, repo: "hexpm", optional: false]}, {:mime, "~> 1.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug, "~> 1.2", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm"},
"raxx_cookie": {:hex, :raxx_cookie, "0.1.0", "caa7304180dcedfc166d28648c3a1baa142d89e2aa9a5406616f76686a8bedb7", [:mix], [], "hexpm"},
"raxx_static": {:hex, :raxx_static, "0.3.0", "1c49edf960227e7125a388355fcc8a2419fea52d6f36cc6cc09d9efb854b0a87", [:mix], [{:raxx, "~> 0.11.0", [hex: :raxx, repo: "hexpm", optional: false]}], "hexpm"},
"server_sent_event": {:hex, :server_sent_event, "0.1.0", "bdc746a63ac5b8c2dbeb6235fd91b4dd662ce9c92e8547c58c2a0e3a647f551b", [:mix], [], "hexpm"},
"ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.1", "28a4d65b7f59893bc2c7de786dec1e1555bd742d336043fe644ae956c3497fbe", [:make, :rebar], [], "hexpm"},
"tokumei": {:hex, :tokumei, "0.6.3", "edf6c03229d59e88271079b92945fd4166fa5c1926220f1136ec054bd051a47c", [:mix], [{:ace_http, "~> 0.4.5", [hex: :ace_http, repo: "hexpm", optional: true]}, {:raxx, "~> 0.11.1", [hex: :raxx, repo: "hexpm", optional: false]}, {:raxx_cookie, "~> 0.1.0", [hex: :raxx_cookie, repo: "hexpm", optional: false]}, {:raxx_static, "~> 0.3.0", [hex: :raxx_static, repo: "hexpm", optional: false]}], "hexpm"},
"unicode_util_compat": {:hex, :unicode_util_compat, "0.2.0", "dbbccf6781821b1c0701845eaf966c9b6d83d7c3bfc65ca2b78b88b8678bfa35", [:rebar3], [], "hexpm"},
"websocket_client": {:hex, :websocket_client, "1.2.1", "a965ce0be5583c90347400bceca66629e4debd5feb9bd516107e2924bdf39dad", [:rebar3], [], "hexpm"},
"wobserver": {:hex, :wobserver, "0.1.7", "377b9a2903728b62e4e89d4e200ec17d60669ccdd3ed72b23a2ab3a2c079694d", [:mix], [{:cowboy, "~> 1.1", [hex: :cowboy, repo: "hexpm", optional: false]}, {:httpoison, "~> 0.11", [hex: :httpoison, repo: "hexpm", optional: false]}, {:plug, "~> 1.3", [hex: :plug, repo: "hexpm", optional: false]}, {:poison, "~> 2.0 or ~> 3.0", [hex: :poison, repo: "hexpm", optional: false]}, {:websocket_client, "~> 1.2", [hex: :websocket_client, repo: "hexpm", optional: false]}], "hexpm"}}
%{"ace": {:hex, :ace, "0.12.1", "c3a997c582158a2f09c99cbc596a53fbb77091f9e7d951e7d0c3d46a9f9ca1f9", [], [{:hpack, "~> 0.2.3", [hex: :hpack_erl, repo: "hexpm", optional: false]}, {:raxx, "~> 0.11.1", [hex: :raxx, repo: "hexpm", optional: false]}], "hexpm"},
"certifi": {:hex, :certifi, "2.0.0", "a0c0e475107135f76b8c1d5bc7efb33cd3815cb3cf3dea7aefdd174dabead064", [], [], "hexpm"},
"cowboy": {:hex, :cowboy, "1.1.2", "61ac29ea970389a88eca5a65601460162d370a70018afe6f949a29dca91f3bb0", [], [{:cowlib, "~> 1.0.2", [hex: :cowlib, repo: "hexpm", optional: false]}, {:ranch, "~> 1.3.2", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm"},
"cowlib": {:hex, :cowlib, "1.0.2", "9d769a1d062c9c3ac753096f868ca121e2730b9a377de23dec0f7e08b1df84ee", [], [], "hexpm"},
"exsync": {:hex, :exsync, "0.2.0", "a460c7c1182a943186bc0b7342a4ceda6955c88549106f13fa58df32b6f7408a", [], [{:file_system, "~> 0.1.3", [hex: :file_system, repo: "hexpm", optional: false]}], "hexpm"},
"file_system": {:hex, :file_system, "0.1.5", "4f20ec7d186cd84ad478bd5477061aeb993b36b5458872041bbabba8b09d36ff", [], [], "hexpm"},
"hackney": {:hex, :hackney, "1.9.0", "51c506afc0a365868469dcfc79a9d0b94d896ec741cfd5bd338f49a5ec515bfe", [], [{:certifi, "2.0.0", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "5.1.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "1.0.1", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "1.0.2", [hex: :mimerl, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "1.1.1", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm"},
"hpack": {:hex, :hpack_erl, "0.2.3", "17670f83ff984ae6cd74b1c456edde906d27ff013740ee4d9efaa4f1bf999633", [], [], "hexpm"},
"http_status": {:hex, :http_status, "0.2.1", "74fa942b5874966a25088162e5297ad52dd5e6a29b88ad4a73953aa55e58e3bb", [], [], "hexpm"},
"httpoison": {:hex, :httpoison, "0.13.0", "bfaf44d9f133a6599886720f3937a7699466d23bb0cd7a88b6ba011f53c6f562", [], [{:hackney, "~> 1.8", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm"},
"idna": {:hex, :idna, "5.1.0", "d72b4effeb324ad5da3cab1767cb16b17939004e789d8c0ad5b70f3cea20c89a", [], [{:unicode_util_compat, "0.3.1", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm"},
"metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [], [], "hexpm"},
"mime": {:hex, :mime, "1.1.0", "01c1d6f4083d8aa5c7b8c246ade95139620ef8effb009edde934e0ec3b28090a", [], [], "hexpm"},
"mimerl": {:hex, :mimerl, "1.0.2", "993f9b0e084083405ed8252b99460c4f0563e41729ab42d9074fd5e52439be88", [], [], "hexpm"},
"plug": {:hex, :plug, "1.4.3", "236d77ce7bf3e3a2668dc0d32a9b6f1f9b1f05361019946aae49874904be4aed", [], [{:cowboy, "~> 1.0.1 or ~> 1.1", [hex: :cowboy, repo: "hexpm", optional: true]}, {:mime, "~> 1.0", [hex: :mime, repo: "hexpm", optional: false]}], "hexpm"},
"poison": {:hex, :poison, "3.1.0", "d9eb636610e096f86f25d9a46f35a9facac35609a7591b3be3326e99a0484665", [], [], "hexpm"},
"ranch": {:hex, :ranch, "1.3.2", "e4965a144dc9fbe70e5c077c65e73c57165416a901bd02ea899cfd95aa890986", [], [], "hexpm"},
"raxx": {:hex, :raxx, "0.11.1", "9e2e8955fae9ecd33dc0a6d9cd50d083b209f3c859c548db0197ce39b9247146", [], [{:http_status, "~> 0.2", [hex: :http_status, repo: "hexpm", optional: false]}, {:mime, "~> 1.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug, "~> 1.2", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm"},
"server_sent_event": {:hex, :server_sent_event, "0.2.1", "4aa61ad29355351872cf9742269b75ecfb908bf64bad830dc4010d815037f9c7", [], [], "hexpm"},
"ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.1", "28a4d65b7f59893bc2c7de786dec1e1555bd742d336043fe644ae956c3497fbe", [], [], "hexpm"},
"unicode_util_compat": {:hex, :unicode_util_compat, "0.3.1", "a1f612a7b512638634a603c8f401892afbf99b8ce93a45041f8aaca99cadb85e", [], [], "hexpm"},
"websocket_client": {:hex, :websocket_client, "1.3.0", "2275d7daaa1cdacebf2068891c9844b15f4fdc3de3ec2602420c2fb486db59b6", [], [], "hexpm"},
"wobserver": {:hex, :wobserver, "0.1.8", "3ed5ea55478627f0593800ab83919b71f41fd426ec344e71cf1d975e6d2065b8", [], [{:cowboy, "~> 1.1", [hex: :cowboy, repo: "hexpm", optional: false]}, {:httpoison, "~> 0.11 or ~> 0.12", [hex: :httpoison, repo: "hexpm", optional: false]}, {:plug, "~> 1.3 or ~> 1.4", [hex: :plug, repo: "hexpm", optional: false]}, {:poison, "~> 2.0 or ~> 3.1", [hex: :poison, repo: "hexpm", optional: false]}, {:websocket_client, "~> 1.2", [hex: :websocket_client, repo: "hexpm", optional: false]}], "hexpm"}}

0 comments on commit ab2446a

Please sign in to comment.