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 apps in one server
Pass :apps (or set SOCKETELX_APPS to a JSON array) to serve several
Pusher apps from one port. Each app has its own id, key and secret, and is
completely isolated: channels, presence, webhooks, limits and metrics are
never shared between apps.
{Socketelx,
name: MyApp.Socketelx,
port: 6001,
apps: [
[id: "chat", key: "chat-key", secret: "chat-secret",
allowed_origins: ["https://chat.example.com"]],
[id: "admin", key: "admin-key", secret: "admin-secret",
webhook_url: "https://admin.example.com/hooks"]
]}Everything else you pass (limits, Redis, cluster settings, ...) applies to
every app unless an app sets it itself. When calling trigger/5 or
authorize_channel/4 on a multi-app server, say which app with app: "chat".
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 user in for pusher-js's pusher.signin(). Call it from the endpoint
pusher-js is configured to use as userAuthentication.endpoint, after you
have identified the user, and reply with the returned map as JSON.
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
Signs a user in for pusher-js's pusher.signin(). Call it from the endpoint
pusher-js is configured to use as userAuthentication.endpoint, after you
have identified the user, and reply with the returned map as JSON.
user must have an :id (a string or integer). Once signed in, events
triggered on the channel "#server-to-user-<id>" reach every connection
of that user.
Socketelx.authenticate_user(MyApp.Socketelx, socket_id, %{id: "42", name: "Ada"})
#=> %{auth: "app-key:...", user_data: "{\"id\":\"42\",\"name\":\"Ada\"}"}
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. On a
multi-app server pass app: "<app id>".
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\",...}"}
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.
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.
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):app: the app id, needed only when the server serves several apps
Example
Socketelx.trigger(MyApp.Socketelx, "chat", "message", %{text: "hi"})