Build Your Own MQTT Broker with EMQX and Docker – Step‑by‑Step Guide
This tutorial walks through installing EMQX as an MQTT broker using Docker, configuring the server, and creating PHP publisher and subscriber clients with the Workerman MQTT library, plus WebSocket and MQTT.js examples for full end‑to‑end IoT communication.
Overview
MQTT (Message Queuing Telemetry Transport) is a lightweight publish/subscribe protocol built on TCP/IP. It is widely used in IoT because it requires minimal code and bandwidth while providing reliable real‑time messaging. EMQX is an open‑source MQTT broker that can be self‑hosted to gain full control over scalability and flexibility.
Deploy EMQX Broker with Docker
Pull the Docker image
docker pull emqx/emqxRun the container
docker run -d --name emqx \
-p 1883:1883 \
-p 8083:8083 \
-p 8084:8084 \
-p 8883:8883 \
-p 18083:18083 \
emqx/emqx:latestAccess the management dashboard
Open http://localhost:18083 in a browser. The default credentials are admin / public. The dashboard shows client connections, broker status, and topic statistics.
PHP MQTT client using Workerman
Install the library
composer require workerman/mqttSubscriber script (subscribe.php)
Run the script with php subscribe.php start. It connects to the broker, subscribes to the resty topic, and prints received messages.
<?php
declare(strict_types=1);
require __DIR__ . '/../vendor/autoload.php';
use Workerman\Worker;
$worker = new Worker();
$worker->onWorkerStart = function () {
$options = ['username' => 'Tinywan', 'password' => '123456'];
$mqtt = new Workerman\Mqtt\Client('mqtt://192.168.13.168:1883', $options);
$mqtt->onConnect = function ($mqtt) {
$mqtt->subscribe('resty');
};
$mqtt->onMessage = function ($topic, $content) {
echo "[Subscriber][Topic]: $topic" . PHP_EOL;
echo "[Subscriber][Content]: $content" . PHP_EOL;
};
$mqtt->connect();
};
Worker::runAll();
?>Publisher script (publish.php)
Run the script with php publish.php start. It publishes the payload Hello Tinywan mqtt to the same resty topic.
<?php
declare(strict_types=1);
require __DIR__ . '/../vendor/autoload.php';
use Workerman\Worker;
$worker = new Worker();
$worker->onWorkerStart = function () {
$mqtt = new Workerman\Mqtt\Client('mqtt://192.168.13.168:1883');
$mqtt->onConnect = function ($mqtt) {
$mqtt->publish('resty', 'Hello Tinywan mqtt');
};
$mqtt->connect();
};
Worker::runAll();
?>WebSocket client with MQTT.js
Include the MQTT.js library in an HTML page and connect to EMQX via the WebSocket endpoint ws://localhost:8083/mqtt. The example below provides a minimal UI to publish arbitrary messages and display received messages.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>MQTT Demo</title>
</head>
<body>
<h3>MQTT WebSocket Demo</h3>
<label>Topic:<input id="targetTopicInput" type="text"></label><br>
<label>Message:<input id="messageInput" type="text"></label><br>
<button onclick="sendMessage()">Send</button>
<button onclick="clearMessage()">Clear</button>
<div id="messageDiv"></div>
<script src="https://unpkg.com/mqtt/dist/mqtt.min.js"></script>
<script>
const url = 'ws://localhost:8083/mqtt';
const topic = 'resty';
const client = mqtt.connect(url);
client.on('connect', () => client.subscribe(topic));
client.on('message', (t, msg) => showMessage('[Subscriber] ' + msg.toString()));
function sendMessage() {
const t = document.getElementById('targetTopicInput').value;
const m = document.getElementById('messageInput').value;
client.publish(t, m);
showMessage('[Sent] ' + t + ': ' + m);
}
function clearMessage() { document.getElementById('messageDiv').innerHTML = ''; }
function showMessage(msg) {
const d = document.getElementById('messageDiv');
const e = document.createElement('div');
e.innerText = msg;
d.appendChild(e);
}
</script>
</body>
</html>Key concepts
Publisher : sends messages to a topic.
Subscriber : receives messages from topics it has subscribed to.
Broker : mediates between publishers and subscribers.
Topic : routing key used for message distribution.
Payload : the actual message content.
QoS levels :
QoS 0 – at most once (no guarantee).
QoS 1 – at least once (possible duplicates).
QoS 2 – exactly once (no duplicates).
Summary
This guide demonstrates how to:
Deploy an EMQX MQTT broker using Docker.
Interact with the broker from PHP using the asynchronous workerman/mqtt library (subscriber and publisher examples).
Use a WebSocket client built with MQTT.js to publish and receive messages from a browser.
Understanding the publish/subscribe flow, QoS options, and the available client libraries enables reliable messaging for IoT applications across industrial control, smart homes, and smart city scenarios.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Open Source Tech Hub
Sharing cutting-edge internet technologies and practical AI resources.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
