Play across machines over BEAM distribution: one machine hosts, the other joins its
worlds (Cauldron2D.Worlds.world_name/2).
{:ok, host} = Cauldron2D.Distribution.host("nidhox", game: "NidhOX")
host.address
host.code
{:ok, node} = Cauldron2D.Distribution.join("nidhox", "192.168.1.5", "K7QMW2ZD")host/2 names this VM <name>@cauldron.host, a name tied to none of the machine's
addresses, gives it a fresh join code (code_length/0 characters of alphabet/0) as
its cookie, and calls on the local network (Cauldron2D.Beacon) with the node's name
and address, this machine's first address (addresses/0). The code never goes over
the air: the host shows it, and whoever joins types it.
join/3 names this VM too when it is not yet distributed, points the host's name at
the address given, in this VM's own host table (looked up before the system's), and
connects to the host's node with the code as the cookie for that node alone. Any of
the host's addresses joins it — its home network's, a VPN's, or 127.0.0.1 from the
same machine.
Rules a caller must respect:
- a connected node can run any code in this VM, so the join code is to be shown
only to the player joining, and a host stopped (
stop/1) once play is over - distribution traffic is not encrypted; play across the internet needs the host's
ports
4369(the node name service) and the:portgiven tohost/2open to the joining machine; without:portthe host listens on any free port - a VM that is already distributed hosts under its own name, with its cookie as
the code, and
stop/1leaves its distribution running
Summary
Functions
This machine's IPv4 address on its local network, the first of addresses/0;
{:error, :no_network} when it has none.
Every IPv4 address of this machine's interfaces that are up, loopback aside: private
network addresses before others, and within each, those of physical interfaces
(named en…, eth… or wl…) before virtual ones such as a VPN's or a virtual
machine's bridge. A machine on several networks is reached at the one its peer shares.
The characters a join code is made of.
A fresh join code.
How many characters a join code has.
Host as name: this VM distributed as <name>@cauldron.host with a fresh join code, and
calling on the local network as :game (default name). :port is the port other
nodes connect on (default any free port). The beacon is linked to the caller.
Join the node <name>@<address> with join code code: {:ok, node} once connected,
else why not —
Types
Functions
@spec address() :: {:ok, String.t()} | {:error, :no_network}
This machine's IPv4 address on its local network, the first of addresses/0;
{:error, :no_network} when it has none.
@spec addresses() :: [String.t()]
Every IPv4 address of this machine's interfaces that are up, loopback aside: private
network addresses before others, and within each, those of physical interfaces
(named en…, eth… or wl…) before virtual ones such as a VPN's or a virtual
machine's bridge. A machine on several networks is reached at the one its peer shares.
@spec alphabet() :: charlist()
The characters a join code is made of.
@spec code() :: String.t()
A fresh join code.
@spec code_length() :: pos_integer()
How many characters a join code has.
Host as name: this VM distributed as <name>@cauldron.host with a fresh join code, and
calling on the local network as :game (default name). :port is the port other
nodes connect on (default any free port). The beacon is linked to the caller.
Join the node <name>@<address> with join code code: {:ok, node} once connected,
else why not —
{:error, :bad_address}—addressis not an IPv4 address{:error, :unreachable}— nothing answers ataddress(its port 4369, where nodes are looked up, is closed or blocked){:error, :not_hosting}— the machine answers, but no nodenameruns there{:error, :refused}— the node runs, but the connection fails: the code is not its code, or its own port is blocked{:error, :no_network}andNode.start/2's errors — this machine cannot be a node
@spec stop(host()) :: :ok
Stop hosting: no more calls on the network, and the distribution host/2 started stopped.