Socketelx (socketelx v0.2.0)

Copy Markdown View Source

Embed a Pusher-protocol-compatible websocket server in your own application's supervision tree:

children = [
  {Socketelx,
   name: MyApp.Socketelx,
   port: 4001,
   app_key: "my-key",
   app_secret: "my-secret",
   app_id: "my-app-id"}
]

Every option can be omitted; it falls back to the SOCKETELX_APP_KEY / SOCKETELX_APP_SECRET / SOCKETELX_APP_ID / PORT / SOCKETELX_WEBHOOK_URL / SOCKETELX_ENABLE_CLIENT_MESSAGES / SOCKETELX_REDIS_URL environment variables (the same ones the standalone Docker release reads), so this also works with zero config for the common case of one instance per app.

Running several servers

Add redis_url: "redis://host:6379" (or set SOCKETELX_REDIS_URL) on every node and they behave as one: a client connected to node A receives events triggered through node B, presence is shared, and member_added/channel_occupied-style events fire once cluster-wide. Every node must use the same app_id/app_key/app_secret.

Redis is optional — without :redis_url an instance is fully in-memory and never opens a Redis connection.

Several instances in one app

Running more than one named instance in the same app (e.g. two different Pusher app_ids on two different ports) works too — just give each a unique :name. Each instance gets its own channel registry and presence state; they never see each other's connections or channels.

Summary

Functions

Signs a client's request to join a private or presence channel and returns the map your auth endpoint should reply with as JSON.

Stops this node from accepting new connections and tells every currently-connected client to reconnect (a clean pusher:error + close frame instead of the socket just dying). With several nodes behind a load balancer, clients reconnect to a node that is still up.

Starts one instance (its supervisor, registry, backend processes and HTTP/WebSocket listener).

Sends an event to every subscriber of channel (on every node, with Redis) without going through the HTTP API. This is how an embedding app publishes.

Functions

authorize_channel(name, socket_id, channel, opts \\ [])

@spec authorize_channel(atom(), String.t(), String.t(), keyword()) :: map()

Signs a client's request to join a private or presence channel and returns the map your auth endpoint should reply with as JSON.

Call it from the endpoint pusher-js is configured to use (channelAuthorization.endpoint) after you have decided the user may join. For a presence channel pass user_id and optionally user_info.

Examples

Socketelx.authorize_channel(MyApp.Socketelx, socket_id, "private-room-1")
#=> %{auth: "app-key:9c1f..."}

Socketelx.authorize_channel(MyApp.Socketelx, socket_id, "presence-room-1",
  user_id: "42", user_info: %{name: "Ada"})
#=> %{auth: "app-key:...", channel_data: "{\"user_id\":\"42\",...}"}

drain(name \\ Socketelx)

Stops this node from accepting new connections and tells every currently-connected client to reconnect (a clean pusher:error + close frame instead of the socket just dying). With several nodes behind a load balancer, clients reconnect to a node that is still up.

Call this from your own app's shutdown path if you embed Socketelx; the standalone release calls it automatically on SIGTERM.

start_link(opts \\ [])

Starts one instance (its supervisor, registry, backend processes and HTTP/WebSocket listener).

Usually you don't call this directly; add {Socketelx, opts} to your supervision tree instead. See Socketelx.Config for every option.

trigger(name, channel, event, data, opts \\ [])

@spec trigger(atom(), String.t(), String.t(), term(), keyword()) :: :ok

Sends an event to every subscriber of channel (on every node, with Redis) without going through the HTTP API. This is how an embedding app publishes.

data is sent as a JSON string, as Pusher does: pass a string to send it untouched, or any term Jason can encode.

Options

  • :socket_id: skip this connection (the sender, usually)

Example

Socketelx.trigger(MyApp.Socketelx, "chat", "message", %{text: "hi"})