# `MqttX.SimpleClient`
[🔗](https://github.com/cignosystems/mqttx/blob/v0.11.2/lib/mqttx/simple_client.ex#L1)

Runtime for `use MqttX` — a module-based MQTT client (GitHub issue #1).

    defmodule MyClient do
      use MqttX

      @impl true
      def init(opts) do
        {:ok, %{count: 0}}
      end

      @impl true
      def handle_message(topic, payload, _packet, state) do
        # Publishing from inside a callback is safe: callbacks run in
        # their own process, not inside the connection.
        publish("replies/" <> Enum.join(topic, "/"), "got it", qos: 1)
        {:ok, %{state | count: state.count + 1}}
      end
    end

    # In a supervision tree:
    children = [
      {MyClient, host: "broker.example.com", client_id: "my-client"}
    ]

`use MqttX` injects `start_link/1`, `child_spec/1`, and the convenience
functions `publish/2,3`, `subscribe/1,2`, `unsubscribe/1`, `connected?/0`,
and `disconnect/0,1` (which address the process registered under the
module name). Connection options passed to `start_link/1` are the same as
`MqttX.Client.connect/1`; `:name` overrides the registered name (when you
do that, use the `MqttX.SimpleClient` functions with your name instead of
the injected helpers).

## Callbacks

Every callback has a default implementation, so implement only the ones you need.

- `init(opts)` — build the initial state from the `start_link/1` options.
  Default: `{:ok, %{}}`.
- `handle_message(topic, payload, packet, state)` — one incoming PUBLISH.
  `topic` is a list of segments.
- `handle_connected(info, state)` — after CONNACK success (also after
  automatic reconnects); `info` has `:session_present` and `:properties`.
- `handle_disconnected(reason, state)` — connection lost (an automatic
  reconnect follows unless the broker rejection was fatal).
- `handle_publish_error(topic, packet_id, reason_code, state)` — broker
  rejected a QoS 1/2 publish.
- `handle_info(message, state)` — any other message sent to the process.

Each returns `{:ok, state}` or `{:stop, reason, state}`.

# `state`

```elixir
@type state() :: term()
```

# `handle_connected`

```elixir
@callback handle_connected(map(), state()) :: {:ok, state()} | {:stop, term(), state()}
```

# `handle_disconnected`

```elixir
@callback handle_disconnected(term(), state()) ::
  {:ok, state()} | {:stop, term(), state()}
```

# `handle_info`

```elixir
@callback handle_info(term(), state()) :: {:ok, state()} | {:stop, term(), state()}
```

# `handle_message`

```elixir
@callback handle_message(MqttX.Topic.normalized_topic(), binary(), map(), state()) ::
  {:ok, state()} | {:stop, term(), state()}
```

# `handle_publish_error`

```elixir
@callback handle_publish_error(term(), integer() | nil, integer(), state()) ::
  {:ok, state()} | {:stop, term(), state()}
```

# `init`

```elixir
@callback init(keyword()) :: {:ok, state()}
```

# `child_spec`

Returns a specification to start this module under a supervisor.

See `Supervisor`.

# `connected?`

# `disconnect`

# `publish`

# `start_link`

# `subscribe`

# `unsubscribe`

---

*Consult [api-reference.md](api-reference.md) for complete listing*
