|
| 1 | +# Frequently Asked Questions |
| 2 | + |
| 3 | + |
| 4 | + |
| 5 | +## Why should I use this instead of plain MQTT with my own binary protocol? |
| 6 | + |
| 7 | +Plain MQTT with a hand-rolled binary protocol forces every consumer to independently maintain serialisation logic, documentation, and versioning. This explodes in complexity as the number of topics and team members grows. |
| 8 | + |
| 9 | +ProtoMQ eliminates that by making **Protobuf the contract enforced at the broker layer**: |
| 10 | + |
| 11 | +| Concern | Plain MQTT + custom binary | ProtoMQ | |
| 12 | +|---|---|---| |
| 13 | +| Schema definition | Ad-hoc, lives in docs or code comments | Canonical `.proto` files, version-controlled | |
| 14 | +| Consumer bootstrap | Pre-shared, out-of-band | Built-in Service Discovery (`$SYS/discovery/request`) | |
| 15 | +| Type safety | Manual, silently fails on mismatch | Validated at every PUBLISH | |
| 16 | +| CLI tooling | Write your own encoder | `protomq-cli publish --json '{"temp": 22.5}'` | |
| 17 | +| Observability | None | Admin HTTP API: connections, throughput, active schemas | |
| 18 | + |
| 19 | +**When it is not the right choice**: if you control all producers and consumers end-to-end and have no schema-evolution needs, plain MQTT + a single struct is simpler. ProtoMQ's value scales with the number of independently-developed clients and the pace of schema change. |
| 20 | + |
| 21 | +--- |
| 22 | + |
| 23 | +## How do I deploy it to a remote server? |
| 24 | + |
| 25 | +The canonical deployment target is a Linux host running systemd. The `zig build` system handles both compilation and service-file installation in one step. |
| 26 | + |
| 27 | +**Prerequisites on the remote host**: Zig 0.15.2+, `git`. |
| 28 | + |
| 29 | +```bash |
| 30 | +# 1. Clone to the installation directory |
| 31 | +sudo mkdir -p /opt/protomq && sudo chown $USER /opt/protomq |
| 32 | +git clone https://github.com/electricalgorithm/protomq /opt/protomq |
| 33 | + |
| 34 | +# 2. Build and install (cross-compile on the remote host itself) |
| 35 | +# The --prefix flag installs binaries to /opt/protomq/bin/ |
| 36 | +# and the systemd unit to /opt/protomq/etc/systemd/system/ |
| 37 | +cd /opt/protomq |
| 38 | +zig build -Doptimize=ReleaseSafe -Dadmin_server=true --prefix /opt/protomq |
| 39 | + |
| 40 | +# 3. Register and start the systemd service |
| 41 | +sudo ln -sf /opt/protomq/etc/systemd/system/protomq.service \ |
| 42 | + /etc/systemd/system/protomq.service |
| 43 | +sudo systemctl daemon-reload |
| 44 | +sudo systemctl enable --now protomq |
| 45 | + |
| 46 | +# 4. Verify |
| 47 | +systemctl status protomq |
| 48 | +# Expected: Active: active (running) |
| 49 | +``` |
| 50 | + |
| 51 | +The service runs the binary at `/opt/protomq/bin/protomq-server` from the `/opt/protomq` working directory (so it resolves the `schemas/` directory correctly) and restarts automatically on failure. |
| 52 | + |
| 53 | +**Validation** — from any machine that can reach the server: |
| 54 | + |
| 55 | +```bash |
| 56 | +# MQTT connectivity |
| 57 | +./zig-out/bin/protomq-cli connect --host <remote_host> |
| 58 | + |
| 59 | +# Admin API (runs only on loopback; tunnel or run on the host) |
| 60 | +curl -s -H "Authorization: Bearer admin_secret" \ |
| 61 | + http://127.0.0.1:8080/metrics |
| 62 | +# → {"connections":0,"messages_routed":0,"schemas":1,"memory_mb":0} |
| 63 | +``` |
| 64 | + |
| 65 | +> **Security note**: The Admin Server binds to `127.0.0.1:8080` only. Set the `ADMIN_TOKEN` environment variable in the systemd unit before exposing it via an SSH tunnel or reverse proxy. |
| 66 | +
|
| 67 | +--- |
| 68 | + |
| 69 | +## How do I add a new Protobuf schema and map it to a topic? |
| 70 | + |
| 71 | +There are two paths depending on whether you want a rebuild or not. |
| 72 | + |
| 73 | +### Static (requires rebuild) |
| 74 | + |
| 75 | +1. Drop your `.proto` file into the `schemas/` directory. |
| 76 | +2. Open `src/server/tcp.zig` and add a `mapTopicToSchema` call inside `TcpServer.init`: |
| 77 | + |
| 78 | +```zig |
| 79 | +// Load Schemas — already called automatically for every .proto in schemas/ |
| 80 | +try server.schema_manager.loadSchemasFromDir("schemas"); |
| 81 | +
|
| 82 | +// Add your mapping: |
| 83 | +try server.schema_manager.mapTopicToSchema("telemetry/gps", "GpsCoordinate"); |
| 84 | +``` |
| 85 | + |
| 86 | +3. Rebuild and restart: |
| 87 | + |
| 88 | +```bash |
| 89 | +zig build -Doptimize=ReleaseSafe --prefix /opt/protomq |
| 90 | +sudo systemctl restart protomq |
| 91 | +``` |
| 92 | + |
| 93 | +The schema directory is scanned on startup; **every `.proto` file found there is parsed automatically** — you only need to add the topic-to-message-type mapping line. |
| 94 | + |
| 95 | +### Dynamic (no rebuild, requires Admin Server) |
| 96 | + |
| 97 | +If the server was built with `-Dadmin_server=true`, you can register a schema at runtime without restarting: |
| 98 | + |
| 99 | +```bash |
| 100 | +curl -X POST http://127.0.0.1:8080/api/v1/schemas \ |
| 101 | + -H "Authorization: Bearer ${ADMIN_TOKEN:-admin_secret}" \ |
| 102 | + -H "Content-Type: application/json" \ |
| 103 | + -d '{ |
| 104 | + "topic": "telemetry/gps", |
| 105 | + "message_type": "GpsCoordinate", |
| 106 | + "proto_file_content": "syntax = \"proto3\";\nmessage GpsCoordinate { float lat = 1; float lon = 2; }" |
| 107 | + }' |
| 108 | +# → OK |
| 109 | +``` |
| 110 | + |
| 111 | +The schema is parsed in-process and persisted as `schemas/<MessageType>.proto` on disk. The mapping is live immediately; **no restart needed**. |
| 112 | + |
| 113 | +--- |
| 114 | + |
| 115 | +## How do I build with the Admin Server enabled? |
| 116 | + |
| 117 | +The Admin Server is **off by default** to keep the binary minimal for embedded targets. Enable it at compile time with a single flag: |
| 118 | + |
| 119 | +```bash |
| 120 | +zig build -Dadmin_server=true |
| 121 | +``` |
| 122 | + |
| 123 | +With the flag, the server binary gains an HTTP listener on `127.0.0.1:8080`. Without the flag, the HTTP code is completely absent from the binary — zero overhead, not just disabled. |
| 124 | + |
| 125 | +| Build | Binary size | Memory baseline | Admin API | |
| 126 | +|---|---|---|---| |
| 127 | +| `zig build` | smaller | ~2.6 MB | ✗ | |
| 128 | +| `zig build -Dadmin_server=true` | slightly larger | ~4.0 MB | ✓ | |
| 129 | + |
| 130 | +**Available endpoints** (all require `Authorization: Bearer <ADMIN_TOKEN>`): |
| 131 | + |
| 132 | +| Method | Path | Description | |
| 133 | +|---|---|---| |
| 134 | +| `GET` | `/metrics` | Active connections, messages routed, loaded schemas | |
| 135 | +| `GET` | `/api/v1/schemas` | Current topic-to-message-type mappings | |
| 136 | +| `POST` | `/api/v1/schemas` | Register a new schema and topic mapping at runtime | |
| 137 | + |
| 138 | +The Admin Server runs cooperatively on the same event loop as the MQTT broker, so enabling it does **not** degrade per-message MQTT performance. |
0 commit comments