服务端部署:
依赖插件安装:
# yum -y install openssl-devel
# yum -y install gcc-c++
# yum -y install cmake
其他扩展
# yum install -y c-ares-devel
# yum install -y uuid-devel
# yum install -y libuuid-devel
libwebsockets的安装:
# wget https://github.com/warmcat/libwebsockets/archive/v1.5-stable.zip
# yum -y install unzip
# unzip v1.5-stable.zip
# mkdir -p /usr/local/websocket
# mv libwebsockets-1.5-stable /usr/local/websocket
# cd /usr/local/websocke/libwebsockets-1.5-stable
# cmake .
# make
# make install
mosquitto安装:
# wget https://mosquitto.org/files/source/mosquitto-1.6.7.tar.gz
# tar zxvf mosquitto-1.6.7.tar.gz
# mv mosquitto-1.6.7 /usr/local/mosquitto-1.6.7
修改config.mk配置文件
修改以下为yes,如果前面有#就去掉,保存退出。
WITH_SRV:=yes
WITH_WEBSOCKETS:=yes #支持websocket
WITH_ADNS:=yes
安装:
# make
# make install
阿里云Alibaba Cloud Linux release 3 (Soaring Falcon)安装mosquitto version 1.6.15
sudo yum install mosquitto
程序配置:
mv /etc/mosquitto/mosquitto.conf.example /etc/mosquitto/mosquitto.conf
mv /etc/mosquitto/pwfile.example /etc/mosquitto/pwfile
修改支持websocket,以及websocket端口
# =================================================================
# General configuration
# =================================================================
# Port to use for the default listener.
port 1833
# Choose the protocol to use when listening.
...
protocol mqtt
361 # =================================================================
362 # Extra listeners
363 # =================================================================
365 # Listen on a port/ip address combination. By using this variable
366 # multiple times, mosquitto can listen on more than one port. If
376 # listener port-number [ip address/host name]
377 listener 1834
410 # Choose the protocol to use when listening.
411 # This can be either mqtt or websockets.
412 # Certificate based TLS may be used with websockets, except that only the
413 # cafile, certfile, keyfile and ciphers options are supported.
414 #protocol mqtt
415 protocol websockets
464 certfile /xxx/xxx/xx.pem
465
466 keyfile /xxx/xxx/xx.key
700 allow_anonymous false
718 password_file /etc/mosquitto/pwfile
创建访问用户:
mosquitto_passwd -c /etc/mosquitto/pwfile guest
输入两次密码: test123456
启动程序:
mosquitto -c /etc/mosquitto/mosquitto.conf -d
客户端测试:
一个窗口测试:
mosquitto_sub -t /user/user_1 -h 127.0.0.1 -p 1833 -u guest -P test123456
另外一个窗口测试:
mosquitto_pub -t /user/user_1 -h 127.0.0.1 -p 1833 -u guest -P test123456 -m "hello world"
客户端代码:
javascript:
官网地址:
https://github.com/eclipse/paho.mqtt.javascript
var is_open = true; //是否开启
var is_ok = false;
var mqtt_ip = "";
var mqtt_websocket_port = 1834; #websocket端口
var client_id = "client_1";
var user_pk = 6;
var mqtt_username = "guest";
var mqtt_password = "test123";
function init_mqtt(){
// 信息通知
// Create a client instance
var client = new Paho.MQTT.Client(mqtt_ip, Number(mqtt_websocket_port), client_id);
// set callback handlers
client.onConnectionLost = onConnectionLost;
client.onMessageArrived = onMessageArrived;
// connect the client
client.connect({onSuccess:onConnect,useSSL:true,userName:mqtt_username,password:mqtt_password});
// called when the client connects
function onConnect() {
// Once a connection has been made, make a subscription and send a message.
is_ok = true;
console.log("onConnect");
client.subscribe("/user/user_{user_pk}".format({user_pk:user_pk}));
/* message = new Paho.MQTT.Message("Hello");
message.destinationName = "World";
client.send(message);
*/
}
// called when the client loses its connection
function onConnectionLost(responseObject) {
is_ok = false;
if (responseObject.errorCode !== 0) {
console.log("onConnectionLost:"+responseObject.errorMessage);
var interval = setInterval(function(){
console.log("try to initial mqtt again");
if(is_ok){
clearInterval(interval);
console.log("reconnect ok!");
}else{
init_mqtt();
}
},10000);
}
}
// called when a message arrives
function onMessageArrived(message) {
console.info(message.payloadString);
}
}
if(is_open==true){
init_mqtt();
}
python:
插件: paho-mqtt
监听 subscribe.py
import paho.mqtt.client as mqtt
def on_connect(client, userdata, flags, rc):
client.subscribe('/user/user_1', qos=0) #断开重连之后,重新监听
print("Connected with result code: " + str(rc))
def on_message(client, userdata, msg):
print(msg.topic + " " + str(msg.payload))
client = mqtt.Client()
client.on_connect = on_connect
client.on_message = on_message
client.username_pw_set(
username="guest",
password="test123",
)
client.connect('192.168.133.129', 1883, 600) # 600为keepalive的时间间隔,mqtt端口
client.loop_forever() # 保持连接
执行:
python3 subscribe.py
发布 publish.py
import paho.mqtt.client as mqtt
import sys
def on_connect(client, userdata, flags, rc):
print("Connected with result code: " + str(rc))
def on_message(client, userdata, msg):
print(msg.topic + " " + str(msg.payload))
if __name__ == "__main__":
topic,data = sys.argv[1],sys.argv[2]
client = mqtt.Client()
client.on_connect = on_connect
client.on_message = on_message
client.username_pw_set(
username="guest",
password="test123",
)
client.connect('192.168.133.129', 1883, 600) # 600为keepalive的时间间隔
print(topic,data)
client.publish(topic, payload=data, qos=0)
执行:
python3 publish.py /user/user_1 "hi,boy"
说明:
启动MQTT报错解决
错误信息:mosquitto: error while loading shared libraries: libwebsockets.so.5: cannot open shared object file: No such file or directory
# ln -s /usr/local/lib/libwebsockets.so.5 /usr/lib/libwebsockets.so.5
# ldconfig
错误信息mosquitto_sub: error while loading shared libraries: libmosquitto.so.1: cannot open shared object file: No such file or directory
ln -s /usr/local/lib/libmosquitto.so.1 /usr/lib/libmosquitto.so.1
ldconfig
客户端上下线状态更新
客户端由于网络等原因断开,重连,系统更新设备的在线状态,供管理员实时查看设备是否在线。
实现原理与步骤
1、客户端服务-下线:
客户端连接mqtt服务器时,设置遗嘱onoffTopic和遗嘱消息内容
{"deviceId":"xxx","status":"offline"},
客户端断开时,服务器发送 {"deviceId":"xxx","status":"offline"}到onoffTopic。
2、客户端服务-上线:
客户端连接成功,向onoffTopic 发送{"deviceId":"xxx","status":"online"}消息
3、系统客户端-监听onoffTopic主题
更新设备的状态到数据库
问题
1、mqtt一段时间没有发送数据,客户端会自动断开
解决办法:
a、每次发送的时候建立一个连接,发送完之后,关闭
b、client.loop_forever()方式,断开会重连,但是是阻塞的,需要线程或者进程方式去启动,并访问连接。