The channel a browser joins a room on: one per room per tab, on one socket for the whole page.
defmodule MyAppWeb.IsshoChannel do
use Issho.Channel, instance: MyApp.Issho
end
defmodule MyAppWeb.IsshoSocket do
use Phoenix.Socket
channel "issho:*", MyAppWeb.IsshoChannel
def connect(_params, socket, _info), do: {:ok, socket}
def id(_socket), do: nil
end
# In the endpoint:
socket "/issho/socket", MyAppWeb.IsshoSocket, websocket: [max_frame_size: 1_000_000]The topic is "issho:" <> room, and the join carries a token signed by
your LiveView (Issho.Token.sign/4). The token says who the actor is
and what it may do; the policy (Issho.Policy) is asked on join, on
every message from the browser, and before each change to a document
goes out to it.
Messages
From the browser, each with a reply:
"open",%{"doc" => id, "pending" => [transaction ids]}: opens a document of the room; replies its snapshot, and which pending transactions (an offline queue's) were already accepted;"tx",%{"doc" => id, "tx" => transaction}: commits a transaction (Issho.Transaction); replies its revision;"aware", a state ornil: the session's awareness (Issho.Awareness);"content",%{"doc" => id, "epoch" => e, "revision" => r}: checks a revision exists, for a form that publishes it.
To the browser: "presence_state" once, "presence_diff", "tx" (a
transaction accepted in an open document), "aware" (a frame of the
others' states) and, when the session ends, "bye" with its reason.