41 lines
1.2 KiB
Elixir
41 lines
1.2 KiB
Elixir
|
|
defmodule ShootingEventPhxWeb.EventsController do
|
||
|
|
use ShootingEventPhxWeb, :controller
|
||
|
|
alias ShootingEventPhx.Events
|
||
|
|
|
||
|
|
def stream(conn, _params) do
|
||
|
|
conn =
|
||
|
|
conn
|
||
|
|
|> put_resp_header("content-type", "text/event-stream")
|
||
|
|
|> put_resp_header("cache-control", "no-cache, no-transform")
|
||
|
|
|> put_resp_header("connection", "keep-alive")
|
||
|
|
|> put_resp_header("x-accel-buffering", "no")
|
||
|
|
|> send_chunked(200)
|
||
|
|
|
||
|
|
now = DateTime.utc_now() |> DateTime.truncate(:second) |> DateTime.to_iso8601()
|
||
|
|
{:ok, conn} = chunk(conn, "event: ready\ndata: {\"ts\":\"#{now}\"}\n\n")
|
||
|
|
|
||
|
|
:ok = Events.subscribe()
|
||
|
|
loop_stream(conn)
|
||
|
|
end
|
||
|
|
|
||
|
|
defp loop_stream(conn) do
|
||
|
|
receive do
|
||
|
|
{:state, ts} ->
|
||
|
|
case chunk(conn, "event: state\ndata: {\"ts\":\"#{ts}\"}\n\n") do
|
||
|
|
{:ok, conn} -> loop_stream(conn)
|
||
|
|
{:error, :closed} -> conn
|
||
|
|
{:error, _} -> conn
|
||
|
|
end
|
||
|
|
after
|
||
|
|
20_000 ->
|
||
|
|
now_unix = DateTime.utc_now() |> DateTime.to_unix()
|
||
|
|
|
||
|
|
case chunk(conn, ": ping #{now_unix}\n\n") do
|
||
|
|
{:ok, conn} -> loop_stream(conn)
|
||
|
|
{:error, :closed} -> conn
|
||
|
|
{:error, _} -> conn
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|