defmodule LSGWeb.IcecastSseController do
use LSGWeb, :controller
require Logger
@ping_interval 20_000
def sse(conn, _params) do
conn
|> put_resp_header("X-Accel-Buffering", "no")
|> put_resp_header("content-type", "text/event-stream")
|> send_chunked(200)
|> subscribe
|> send_sse_message("ping", "ping")
|> send_sse_message("icecast", LSG.IcecastAgent.get)
|> sse_loop
end
def subscribe(conn) do
:timer.send_interval(@ping_interval, {:event, :ping})
{:ok, _} = Registry.register(LSG.BroadcastRegistry, "icecast", [])
conn
end
def sse_loop(conn) do
{type, event} = receive do
{:event, :ping} -> {"ping", "ping"}
{:icecast, stats} -> {"icecast", stats}
end
conn
|> send_sse_message(type, event)
|> sse_loop()
end
defp send_sse_message(conn, type, data) do
json = Jason.encode!(%{type => data})
{:ok, conn} = chunk(conn, "event: #{type}\ndata: #{json}\n\n")
conn
end
end