MQTT is a super lightweight IoT protocol on TCP/IP with …8 bits header. Send and receive messages with others in “topic” like as a chatroom.
Install Mosquitto (MQTT Broker Server)
Install MQTT broker on server
dnf -y install epel-release
dnf -y install mosquitto
systemctl enable mosquitto
systemctl start mosquitto
Create user and password (exp: admin):
mosquitto_passwd -c /etc/mosquitto/passwd admin
Sercurity config:
Open file /etc/mosquitto/mosquitto.conf
to add this config to require password when connect:
allow_anonymous false
password_file /etc/mosquitto/passwd
Config listener port, encrypt, protocol:
Add this content to /etc/mosquitto/mosquitto.conf
:
listener 1883 localhost
# or listener 1883 if open 1883 to network
listener 8883
certfile /etc/letsencrypt/live/domain.com/cert.pem
cafile /etc/letsencrypt/live/domain.com/fullchain.pem
keyfile /etc/letsencrypt/live/domain.com/privkey.pem
listener 8083
protocol websockets
certfile /etc/letsencrypt/live/domain.com/cert.pem
cafile /etc/letsencrypt/live/domain.com/fullchain.pem
keyfile /etc/letsencrypt/live/domain.com/privkey.pem
Restart service
systemctl daemon-reload
systemctl restart mosquitto
Open firewall port
firewall-cmd --permanent --add-port=1883/tcp
firewall-cmd --permanent --add-port=8083/tcpfirewall-cmd --permanent --add-port=8883/tcp
firewall-cmd --reload
Practice MQTT: publish and subscribe
In example, the topic is “test”. So, it can be any thing you want (test/001, myroom/test/001,…).
From your server’s terminal:
A listener:
mosquitto_sub -h localhost -t test -u "admin" -P "Icg...." -p 1883
A publisher:
mosquitto_pub -h localhost -t test -m "hello world" -u "admin" -P "Icg...." -p 1883
From other computer:
From browsers, server url like as: wss://domain.com:8883 (SSL).
A listener:
mosquitto_sub -h domain.com -t test -u "admin" -P "Icg...." -p 8883 --cafile "C:\Program Files\Mosquitto\ca-bundle.crt" --insecure
A publisher:
mosquitto_pub -h domain.com -t test -m "hello world" -u "admin" -P "Icg...." -p 8883 --cafile "C:\Program Files\Mosquitto\ca-bundle.crt" --insecure
ca.crt is the CA certificate file. It’s the same SSL provider’s SSL CA certificate which broker used. Your path is in “” if has space character.
More parameters:
-r: mark as retain message (save this message to send to new subscribers). Just for “pub” command.
-q 0: (0 or 1 or 2) to mark quality:
- 0 send once, accept losing
- 1 send once or more
- 2 send exactly once
– d: write log for debug
– n: Send “null”, so “-m” is not accept
– A 192.0.0.1: Send to exactly IP client you want to send
-f something.txt: send file (string in the file)
-k 60: keep alive in this time (by seconds). After this time, broker and client will ping to check connect is alive or closed.
-I “sometext”: set ClientID prefix. Suffixe is created automaticly.
-i “sometext”: Set Client id exactly
-t: Set Topic name (/topic/ or mix topic):
- /topic/+/t1/: Start with /topic/, many topic, end with /t1/
- /topic/#: All topic start with /topic/
When you send a message to /topic/learning/english/2022/. So all subscribers listen on /topic/
or /learning/
or /english/
or /2022/
, everyone received the message
–will-payload : mark as the message which broker help you to send to your topic when you go out (unsub, or timeout). If not set, the null will be sent.
–will-qos : Set QoS to testament message (the wills)
–will-retain : Save this wills to send to new subscribers.
–will-topic : Set topic you want to send the wills
Your backend app just is a Client!
Demo PHP client (backend)
Source: https://github.com/bluerhinos/phpMQTT
Install by Composer (just fo PHP backend):
composer require bluerhinos/phpmqtt=@dev
Examples folder: vendor/bluerhinos/phpmqtt/examples
Config your connection info.
In subscribe.php
write your custom function to do something when receive a message on topic:
function procMsg($topic, $msg){
echo 'Msg Recieved: ' . date('r') . "\n";
echo "Topic: {$topic}\n\n";
echo "\t$msg\n\n";
}
Your PHP file need to include this library:
require('../phpMQTT.php');
Example: 2 functions to reply message:
function procMsg($topic, $msg){
echo 'Msg Recieved: ' . date('r') . "\n";
echo "Topic: {$topic}\n\n";
echo "\t$msg\n\n";
if($msg == "hello world"){
reply($topic, $msg);
// require("publish.php");
}
}
function reply($topic, $msg){
$server = 'localhost'; // change if necessary
$port = 1883; // change if necessary
$username = 'admin'; // set your username
$password = 'Icg@...'; // set your password
$client_id = 'phpMQTT-publisher1'; // make sure this is unique for connecting to sever - you could use uniqid()
$explode = explode("/", $topic);
$from_client_id = $explode['2'];
$explode['2'] = $client_id;
$new_topic = implode("/",$explode);
// echo $from_client_id;
// $topic_mix = preg_replace($to_client_id, $client_id, $topic);
$mqtt = new Bluerhinos\phpMQTT($server, $port, $client_id);
if ($mqtt->connect(true, NULL, $username, $password)) {
$mqtt->publish($new_topic, 'Yes, Hello '. $from_client_id .' on ' . $new_topic .' at ' . date('r'), 0, false);
$mqtt->close();
} else {
echo "Time out!\n";
}
}