Skip to content

Instantly share code, notes, and snippets.

@ream88
Created October 30, 2023 21:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ream88/6b1db83c21a0a51cb8459df1bad0ada0 to your computer and use it in GitHub Desktop.
Save ream88/6b1db83c21a0a51cb8459df1bad0ada0 to your computer and use it in GitHub Desktop.
A compact Bandit HTTP server capable of replaying SSE events, such as those generated by ChatGPT
Mix.install([
{:bandit, ">= 1.0.0"}
])
defmodule SSE do
use Plug.Builder
require Logger
def init(options), do: options
def call(conn, _opts) do
conn
|> put_resp_content_type("text/event-stream")
|> send_chunked(200)
|> stream()
end
defp stream(conn) do
File.stream!("response.txt")
|> Enum.reduce_while(conn, fn chunk, conn ->
case Plug.Conn.chunk(conn, chunk) do
{:ok, conn} ->
:timer.sleep(25)
{:cont, conn}
{:error, :closed} ->
{:halt, :disconnect}
end
end)
|> case do
:disconnect ->
Logger.warn("Client disconnected")
conn
conn ->
conn
end
|> Plug.Conn.halt()
end
end
bandit = {Bandit, plug: SSE, scheme: :http}
{:ok, _} = Supervisor.start_link([bandit], strategy: :one_for_one)
# unless running from IEx, sleep indefinitely so we can serve requests
unless IEx.started?() do
Process.sleep(:infinity)
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment