请问技术:微信小程序订阅主题指令:this.data.client.subscribe(this.data.subTopic, {noLocal: true});执行后主题订阅成功,收发数据也正常,但禁止本地转发的指令未起作用,在EMQX服务器侧查看,禁止本地转发栏始终为false,请问这是怎么回事呢?谢谢!
客户端指定的mqtt 版本是5.0 ?
客户端指定的mqtt 版本是5.0
以下代码是微信小程序MQTT测试程序:
import mqtt from “…/…/utils/mqtt.min.js”;
// 连接字符串, 通过协议指定使用的连接方式
// ws 未加密 WebSocket 连接
// wss 加密 WebSocket 连接
// mqtt 未加密 TCP 连接
// mqtts 加密 TCP 连接
// wxs 微信小程序连接
// alis 支付宝小程序连接
Page({
data: {
client: null,
conenctBtnText: “连接”,
// host: “wx.emqxcloud.cn”,//err(连接此服务器始终失败!)
// host: “broker.emqx.io”,//ok(此为EMQX免费云MQTT服务器地址,只在编译后的模拟器中测试ok,在预览后扫码的手机端测试err!)
host: “127.0.0.1”,//ok(此为本机EMQX之MQTT服务器地址,只在编译后的模拟器中测试ok,在预览后扫码的手机端测试err!)
// host: “172.20.10.5”,//ok(此为本机EMQX之MQTT服务器地址,只在编译后的模拟器中测试ok,在预览后扫码的手机端测试err!)
subTopic: “testtopic/miniprogram”, //订阅主题
pubTopic: “testtopic/miniprogram_p”,//发布主题
pubMsg: “请开灯”,
receivedMsg: “”,
// noLocal: true,//为 1 表示服务端不能将消息转发给发布这个消息的客户端,为 0 则相反。
mqttOptions: {//连接选项
//基础
// protocol: ‘wxs’,
// clientId: ‘1703667720243’,//13bit 客户端 ID
clientId: ‘gh_701570474708_21a_sj’,//客户端 ID
username: “21A手机”,//连接用户名(可选)
password: “123456”,//连接密码(可选)
// ssl: true,
// useSSL: true,
// alpn: “”,
// rejectUnauthorized: true,//返回未授权(TLS?):false,true
// ca: CA_CERT,//err
//高级
protocolVersion: 5,//协议版本:MQTT版本5.0
connectTimeout: 30 * 1000, //连接超时时间: 30秒
keepalive: 60,//心跳时间,默认 60秒,设置 0 为禁用
resubscribe: true, // 如果连接断开并重新连接,则会再次自动订阅已订阅的主题(默认true)
reconnectPeriod: 1000, //重连周期: 1000毫秒,设置为 0 禁用自动重连,两次重新连接之间的间隔时间
clean: true,//Clean Start设置–true: 清除会话, false: 保留会话
SessionExpiryInterval:5000,//指定网络连接断开后会话的过期时间。设置为 0 或未设置,表示断开连接时会话即到期;设置为大于 0 的数值,则表示会话在网络连接关闭后会保持多少秒;设置为 0xFFFFFFFF 表示会话永远不会过期。
qos: 0,
retain: false,//保留消息:true(保留);false(不保留)
// 更多参数请参阅 MQTT.js 官网文档:https://github.com/mqttjs/MQTT.js#mqttclientstreambuilder-options
// 更多 EMQ 相关 MQTT 使用教程可在 EMQ 官方博客中进行搜索:https://www.emqx.com/zh/blog
},
},
setValue(key, value) {
this.setData({
[key]: value,
});
},
setHost(e) {
this.setValue(“host”, e.detail.value);
},
setSubTopic(e) {
this.setValue(“subTopic”, e.detail.value);
},
setPubTopic(e) {
this.setValue(“pubTopic”, e.detail.value);
},
setPubMsg(e) {
this.setValue(“pubMsg”, e.detail.value);
},
setRecMsg(msg) {
this.setValue(“receivedMsg”, msg);
},
connect() {
// MQTT-WebSocket 统一使用 /path 作为连接路径,连接时需指明,但在 EMQX Cloud 部署上使用的路径为 /mqtt
// 因此不要忘了带上这个 /mqtt !!!
// 微信小程序的wx对应ws协议,wxs对应wss协议: 微信小程序中需要将 wss 协议写为 wxs,且由于微信小程序出于安全限制,不支持 ws 协议
try {
this.setValue(“conenctBtnText”, “连接中…”);
//old
// const clientId = new Date().getTime();
// this.data.client = mqtt.connect(wxs://${this.data.host}:8084/mqtt
, {
// …this.data.mqttOptions,
// clientId,
// });
// clientIds=clientId;
// this.setValue(“clientId”,clientId);
//new
// this.data.client = mqtt.connect(wx://${this.data.host}:8083/mqtt
,this.data.mqttOptions);//ok(服务器连接成功:只在编译后的模拟器中测试ok,在预览后扫码的手机端测试err!)
this.data.client = mqtt.connect(wxs://${this.data.host}:8084/mqtt
,this.data.mqttOptions);//ok(服务器连接成功:只在编译后的模拟器中测试ok,在预览后扫码的手机端测试err!)
this.data.client.on("connect", () => {
wx.showToast({
title: "服务器连接成功",
});
this.setValue("conenctBtnText", "连接成功");
this.data.client.on("message", (topic, payload) => {
wx.showModal({
content: `收到消息 - Topic: ${topic},Payload: ${payload}`,
showCancel: false,
});
const currMsg = this.data.receivedMsg ? `<br/>${payload}` : payload;
this.setValue("receivedMsg", this.data.receivedMsg.concat(currMsg));
});
this.data.client.on("error", (error) => {
this.setValue("conenctBtnText", "连接");
console.log("onError", error);
});
this.data.client.on("reconnect", () => {
this.setValue("conenctBtnText", "连接");
console.log("reconnecting...");
});
this.data.client.on("offline", () => {
this.setValue("conenctBtnText", "连接");
console.log("onOffline");
});
// 更多 MQTT.js 相关 API 请参阅 https://github.com/mqttjs/MQTT.js#api
});
} catch (error) {
this.setValue("conenctBtnText", "连接");
console.log("mqtt.connect error", error);
}
},
subscribe() {
// var subscribeOption = {
// noLocal : true,
// };
if (this.data.client) {
// this.data.client.subscribe(this.data.subTopic, {noLocal: true}); //对于“禁止本地转发”无任何作用!
// this.data.client.subscribe(this.data.subTopic, {noLocal: false});//对于“禁止本地转发”无任何作用!
// this.data.client.subscribe(this.data.subTopic, this.options = SubscribeOptions(noLocal = True));
this.data.client.subscribe(this.data.subTopic); //对于微信小程序客户端和MQTTX客户端:只有订阅主题和发布主题不相等或不相同时,方可禁止自发自收!
wx.showModal({
content: 成功订阅主题:${this.data.subTopic}
,
showCancel: false,
});
return;
}
wx.showToast({
title: “请先点击连接”,
icon: “error”,
});
},
unsubscribe() {
if (this.data.client) {
this.data.client.unsubscribe(this.data.subTopic);
wx.showModal({
content: 成功取消订阅主题:${this.data.subTopic}
,
showCancel: false,
});
return;
}
wx.showToast({
title: “请先点击连接”,
icon: “error”,
});
},
publish() {
if (this.data.client) {
this.data.client.publish(this.data.pubTopic, this.data.pubMsg);
return;
}
wx.showToast({
title: “请先点击连接”,
icon: “error”,
});
},
disconnect() {
this.data.client.end();
this.data.client = null;
this.setValue(“conenctBtnText”, “连接”);
wx.showToast({
title: “成功断开连接”,
});
},
});
以下代码是微信小程序MQTT测试程序:
import mqtt from “…/…/utils/mqtt.min.js”;
Page({
data: {
client: null,
conenctBtnText: “连接”,
host: “127.0.0.1”,//ok(此为本机EMQX之MQTT服务器地址,只在编译后的模拟器中测试ok,在预览后扫码的手机端测试err!)
subTopic: “testtopic/miniprogram”, //订阅主题
pubTopic: “testtopic/miniprogram_p”,//发布主题
pubMsg: “请开灯”,
receivedMsg: “”,
// noLocal: true,//为 1 表示服务端不能将消息转发给发布这个消息的客户端,为 0 则相反。
mqttOptions: {//连接选项
//基础
clientId: ‘gh_701570474708_21a_sj’,//客户端 ID
username: “21A手机”,//连接用户名(可选)
password: “123456”,//连接密码(可选)
// ssl: true,
// useSSL: true,
// alpn: “”,
// rejectUnauthorized: true,//返回未授权(TLS?):false,true
// ca: CA_CERT,//err
//高级
protocolVersion: 5,//协议版本:MQTT版本5.0
connectTimeout: 30 * 1000, //连接超时时间: 30秒
keepalive: 60,//心跳时间,默认 60秒,设置 0 为禁用
resubscribe: true, // 如果连接断开并重新连接,则会再次自动订阅已订阅的主题(默认true)
reconnectPeriod: 1000, //重连周期: 1000毫秒,设置为 0 禁用自动重连,两次重新连接之间的间隔时间
clean: true,//Clean Start设置–true: 清除会话, false: 保留会话
SessionExpiryInterval:5000,//指定网络连接断开后会话的过期时间。设置为 0 或未设置,表示断开连接时会话即到期;设置为大于 0 的数值,则表示会话在网络连接关闭后会保持多少秒;设置为 0xFFFFFFFF 表示会话永远不会过期。
qos: 0,
retain: false,//保留消息:true(保留);false(不保留)
},
},
connect() {
try {
this.setValue(“conenctBtnText”, “连接中…”);
this.data.client = mqtt.connect(wxs://${this.data.host}:8084/mqtt
,this.data.mqttOptions);//ok(服务器连接成功:只在编译后的模拟器中测试ok,在预览后扫码的手机端测试err!)
this.data.client.on(“connect”, () => {
wx.showToast({
title: “服务器连接成功”,
});
this.setValue(“conenctBtnText”, “连接成功”);
this.data.client.on("message", (topic, payload) => {
wx.showModal({
content: `收到消息 - Topic: ${topic},Payload: ${payload}`,
showCancel: false,
});
const currMsg = this.data.receivedMsg ? `<br/>${payload}` : payload;
this.setValue("receivedMsg", this.data.receivedMsg.concat(currMsg));
});
this.data.client.on("error", (error) => {
this.setValue("conenctBtnText", "连接");
console.log("onError", error);
});
this.data.client.on("reconnect", () => {
this.setValue("conenctBtnText", "连接");
console.log("reconnecting...");
});
this.data.client.on("offline", () => {
this.setValue("conenctBtnText", "连接");
console.log("onOffline");
});
// 更多 MQTT.js 相关 API 请参阅 https://github.com/mqttjs/MQTT.js#api
});
} catch (error) {
this.setValue("conenctBtnText", "连接");
console.log("mqtt.connect error", error);
}
},
subscribe() {
if (this.data.client) {
this.data.client.subscribe(this.data.subTopic, {noLocal: true}); //测试结果显示:虽然订阅成功,但对于“禁止本地转发”无任何作用! 待解决…
wx.showModal({
content: 成功订阅主题:${this.data.subTopic}
,
showCancel: false,
});
return;
}
wx.showToast({
title: “请先点击连接”,
icon: “error”,
});
},
unsubscribe() {
if (this.data.client) {
this.data.client.unsubscribe(this.data.subTopic);
wx.showModal({
content: 成功取消订阅主题:${this.data.subTopic}
,
showCancel: false,
});
return;
}
wx.showToast({
title: “请先点击连接”,
icon: “error”,
});
},
publish() {
if (this.data.client) {
this.data.client.publish(this.data.pubTopic, this.data.pubMsg);
return;
}
wx.showToast({
title: “请先点击连接”,
icon: “error”,
});
},
disconnect() {
this.data.client.end();
this.data.client = null;
this.setValue(“conenctBtnText”, “连接”);
wx.showToast({
title: “成功断开连接”,
});
},
});