Eclipse Paho 项目提供了 MQTT 消息传递协议的开源客户端实现,官网如下
https://www.eclipse.org/paho/
Eclipse paho 项目提供了如下语言的库:
Java
Python
JavaScript
GoLang
C
C++
Rust
Net (C#)
Android Service
Embedded C/C++
针对这些语言的提供的 MQTT 客户端库目前对 MQTT 协议的支持情况如下:


1、paho-mqtt.js默认使用的是WebSocket连接,所以端口号应使用配置中ws对应的端口号,而非tcp对应的端口号。因此需要修改 mosquitto.conf。
#protocol mqtt listener 1883 protocol mqtt listener 1884 protocol websockets
2、编写一个JavaScript应用。

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title></title>
<meta charset="utf-8" />
<script src="js/jquery.min.js"></script>
<script src="js/paho-mqtt.js"></script>
<script type="text/javascript">
// 客户端选项
var option = {
"ServerUri": "192.168.124.5",
"ServerPort": 1884,
"UserName": "jzh",
"Password": "111111",
"ClientId": "",
"TimeOut": 5,
"KeepAlive": 100,
"CleanSession": false,
"SSL":false
}
// 客户端
var client;
$(function () {
// 连接按钮点击事件
$("#btnConnect").on("click", function () {
if ($("#txtIp").val()!="") {
option.ServerUri = $("#txtIp").val();
}
else {
alert("请输入服务端IP!");
return;
}
if($("#txtPort").val()!=""){
option.ServerPort = Number($("#txtPort").val());
}
else {
alert("请输入端口号!");
return;
}
option.ClientId = makeid();
client = new Paho.Client(option.ServerUri, option.ServerPort, option.ClientId)
client.onConnectionLost = onConnectionLost;
client.onMessageArrived = onMessageArrived;
client.connect({
invocationContext: {
host: option.ServerUri, // IP地址
port: option.ServerPort, // 端口号
path: client.path,
clientId: option.ClientId // 标识
},
timeout: option.TimeOut, // 连接超时时间
keepAliveInterval: option.KeepAlive, // 心跳间隔
cleanSession: option.CleanSession, // 是否清理Session
useSSL: option.SSL, // 是否启用SSL
userName: option.UserName, // 用户名
password: option.Password, // 密码
onSuccess: onConnect, // 连接成功回调事件
onFailure: onError // 连接失败回调事件
});
});
// 断开按钮点击事件
$("#btnDisconnect").on("click", function () {
client = null;
enable($("#btnConnect"), true);
enable($("#btnDisconnect"), false);
enable($("#btnPublish"), false);
enable($("#btnSubscribe"), false);
});
// 订阅按钮点击事件
$("#btnSubscribe").on("click", function () {
if (!client) {
alert("请连接服务端");
return;
}
var topic = $("#txtTopic").val();
client.subscribe(topic);
logInfo("成功订阅主题:" + topic);
});
// 发布按钮点击事件
$("#btnPublish").on("click", function () {
if(!client){
alert("请连接服务端");
return;
}
if($("#txtContent").val()==""){
alert("请输入要发布的内容");
return;
}
var message = new Paho.Message($("#txtContent").val());
var topic = $("#txtTopic").val();
message.destinationName = topic;
client.send(message);
logInfo("发布了主题为" + topic + "的消息:" + $("#txtContent").val())
});
});
// 连接成功事件
function onConnect() {
logInfo("连接成功!")
enable($("#btnConnect"), false);
enable($("#btnDisconnect"), true);
enable($("#btnPublish"), true);
enable($("#btnSubscribe"), true);
}
// 连接失败事件
function onError(e) {
logInfo("连接失败:" + e)
enable($("#btnConnect"), true);
enable($("#btnDisconnect"), false);
enable($("#btnPublish"), false);
enable($("#btnSubscribe"), false);
}
// 连接断开事件
function onConnectionLost(e) {
if (e.errorCode !== 0) {
logInfo("连接异常断开:" + e.errorMessage);
enable($("#btnConnect"), true);
enable($("#btnDisconnect"), false);
enable($("#btnPublish"), false);
enable($("#btnSubscribe"), false);
}
}
// 接收消息事件
function onMessageArrived(data) {
logInfo("收到消息:" + data.payloadString);
}
// 日志输出
function logInfo(data) {
var date = new Date();
var newdate = date.toLocaleString('chinese', { hour12: false, year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit', second: '2-digit' }) // 获取24小时制,打印出 2020/12/23 23:31:12
var fmtdate = newdate.replace(/[\/]/g, "-") // 打印出 2020-12-23 23:31:12
var message = '[' + fmtdate + ']' + data;
console.log(message);
$("#logInfo").append('<li>' + message + '</li>');
}
// clientid
function makeid() {
var text = "";
var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
for (var i = 0; i < 5; i++)
text += possible.charAt(Math.floor(Math.random() * possible.length));
return text;
}
// 切换按钮状态
function enable(button,enabled) {
if (enabled) {
button.removeAttr("disabled");
}
else {
button.attr("disabled", "disabled");
}
}
</script>
</head>
<body>
<table>
<tr>
<td></td>
<td>服务器IP: <input id="txtIp" type="text" value="192.168.124.5"/></td>
<td>WebSocket端口: <input id="txtPort" type="text" value="1884"/></td>
<td><input id="btnConnect" type="button" value="连接"/></td>
<td><input id="btnDisconnect" type="button" value="断开" disabled="disabled"/></td>
<td></td>
</tr>
<tr>
<td></td>
<td colspan="3">
</td>
<td><input id="btnSubscribe" type="button" value="订阅" disabled="disabled"/></td>
<td></td>
</tr>
<tr>
<td></td>
<td colspan="4">
<ul id="logInfo"></ul>
</td>
<td></td>
</tr>
<tr>
<td></td>
<td>
主题: <input id="txtTopic" type="text" value="news" />
</td>
<td colspan="2">消息: <input id="txtContent" type="text"/></td>
<td><input id="btnPublish" type="button" value="发布" disabled="disabled"/></td>
<td></td>
</tr>
</table>
</body>
</html>