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