Current section
Files
Jump to
Current section
Files
lib/sse_phoenix_pubsub.ex
defmodule SsePhoenixPubsub do
@moduledoc """
Server-Sent Events on top of `Phoenix PubSub`.
### Installation
Add to dependencies in mix.exs:
```elixir
{:sse_phoenix_pubsub, "~> 1.0"}
```
### Sending SSE
Start the PubSub system in `application.ex`:
```elixir
{Phoenix.PubSub, name: MyApp.PubSub}
```
Publish messages via `Phoenix.PubSub.broadcast` method on a selected topic:
```elixir
Phoenix.PubSub.broadcast(MyApp.PubSub, "time", {MyApp.PubSub, "01:34:55.123567"})
```
### Receiving SSE
Configure http endpoint for SSE with `idle_timeout` option to keep
the SSE connection running:
```elixir
config :my_app, MyAppWeb.Endpoint,
http: [
port: 4000,
protocol_options: [
idle_timeout: 3_600_000
]
]
```
Configure phoenix or plug routing:
```elixir
pipeline :sse do
plug :put_format, "text/event-stream"
plug :fetch_session
end
scope "/sse", MyAppWeb do
pipe_through :sse
get "/", SseController, :subscribe
end
```
Create a Phoenix controller for subscribing http clients to desired topics:
```elixir
defmodule MyAppWeb.SseController do
use MyAppWeb, :controller
def subscribe(conn, params) do
case get_topics(params) do
topics when is_list(topics) ->
SsePhoenixPubsub.stream(conn, {MyApp.PubSub, topics})
_ ->
Logger.error("No topics provided")
end
end
defp get_topics(params) do
case params["topics"] do
str when is_binary(str) -> String.split(str, ",")
nil -> []
end
end
end
```
"""
defdelegate stream(conn, pubsub_info, data \\ []),
to: SsePhoenixPubsub.Server,
as: :stream
end