The device agent: socket, channel, heartbeat, and dispatch.
This is the only process. nh_channel holds the protocol and nh_metadata
reads the firmware description; both are pure, and this loop is what gives
them a socket and a clock.
The transport is a module, not a hard dependency, so the agent can be driven on a desktop against a real NervesHub before it runs on a chip:
Transport:open(Config) -> {ok, Handle} | {error, term()}
Transport:send_text(Handle, Binary) -> ok | {error, term()}
Transport:close(Handle) -> ok
and it delivers {websocket, Handle, connected | {text, B} | {closed, R} |
{error, R}}. websocket_client from atomvm_websocket_client already has
this shape.
The transport reconnects on its own, so connected arrives more than once.
Every one of them starts a fresh channel join, because a Phoenix channel does
not survive a socket reconnect. This is the whole reason the agent watches for
connected rather than joining once at startup.
receive ... after timeout, so a steady
stream of incoming messages cannot keep pushing the heartbeat out and get the
device disconnected while it looks busy and healthy.
config() = #{url => binary() | string(), host => binary() | string(), identifier := binary(), transport => module(), shared_secret => {binary(), binary()}, client_cert => {binary(), binary()}, verify => term(), metadata => map(), handler => pid(), heartbeat_ms => pos_integer()}
| start/1 | |
| start_link/1 | Start the agent, linked to the caller. |
| stop/1 |
start(Config::config()) -> {ok, pid()} | {error, term()}
start_link(Config::config()) -> {ok, pid()} | {error, term()}
Start the agent, linked to the caller.
stop(Pid::pid()) -> ok
Generated by EDoc