<p><iframe name="ifd" src="https://mnifdv.cn/resource/cnblogs/Learn-NB-IOT-Air302-ForLua" frameborder="0" scrolling="auto" width="100%" height="1500"></iframe></p>
说明
这节测试一下模组连接MQTT服务器,然后和MQTT调试助手互发消息!
这一节把MQTT服务器(软件)安装到本地电脑.
因为模组只能广域网连接通信所以咱再通过花生壳映射下.
安装MQTT软件
1.把下面的软件放到一个没有中文的目录下,并解压
2.我解压到了H盘(随意哈)
3.运行cmd 进入emqttd/bin目录
4.启动服务器(控制台模式),一次启动不起来,再执行一次!
emqttd console
5.提示,如果出现下面的错误,需要拷贝补丁,然后重新执行命令
把补丁拷贝到 Windows/System32里面
6.出现下面的窗口说明服务器已经以控制台模式运行起来了
18083端口是网页端控制台
11883端口是普通TCP连接(仅限于安装MQTT软件的本机上的客户端连接)
1883端口是普通TCP连接
8883端口是TCP SSL
8083端口是WebSocket
8084端口是WebSocket SSL
8080端口是配置MQTT参数
测试MQTT软件是否可以连接
1.打开MQTT调试软件
注:这是我使用C#写的一个MQTT调试助手,含源码
2.查看自己电脑的IP地址
3.测试连接服务器
配置花生壳
1.搜索花生壳
2.下载并安装,注册,登录
3.选择映射配置
4.输入先前注册的账号和密码
5.添加映射
6.按照下面说明填写
7.解释
网络设备访问 IP地址: 358n960z57.wicp.vip 端口号:36548
就能够访问到本机192.168.1.93 上的1883端口的服务器应用程序.
8.使用调试助手测试
使用模组连接
1.安装上手机卡和天线
2.把例程里面的mqtt.lua源码拷贝到user main.lua
3.修改IP地址,端口号,订阅和发布的主题
注:IP地址和端口号就是通过花生壳映射出去的信息
订阅和发布的主题之所以改为简单点,是因为方便咱测试,然后接收到什么数据就返回.
4.编译并下载到开发板,看到订阅成功就说明连接上了
5.用调试助手订阅开发板发布的主题
6.调试助手发送信息给开发板
MQTT文件封装
1.以后做项目,不能把所有的都写到一个文件里面,需要把连接,接收,发送分开.
下面的文件是参考官方202的mqtt的demo修改的.
mqttTask.lua
负责连接MQTT服务器,和轮训发送和接收函数
代码语言:javascript复制local mqttTask = {}
_G.sys = require("sys")
local mqtt = require "mqtt"
local mqttOutMsg = require "mqttOutMsg"
local mqttInMsg = require "mqttInMsg"
local ready = false
--- MQTT连接状态
function mqttTask.isReady()
return ready
end
sys.taskInit(function()
-- 服务器配置信息
local host, port, clientId = "358n960z57.wicp.vip", 36548, nbiot.imei()
mqttOutMsg.set_imei(clientId);
-- 等待联网成功
while true do
while not socket.isReady() do
log.info("net", "wait for network ready")
sys.waitUntil("NET_READY", 1000)
end
local mqttc = mqtt.client(clientId, nil, nil, false)
while not mqttc:connect(host, port) do sys.wait(2000) end
ready = true
local subscribe_topic = "111111" --设备订阅的主题 111111
if mqttc:subscribe(subscribe_topic) then
while true do
if not mqttInMsg.proc(mqttc) then log.error("mqttTask.mqttInMsg.proc error") break end
if not mqttOutMsg.proc(mqttc) then log.error("mqttTask.mqttOutMsg proc error") break end
end
end
ready = false
mqttOutMsg.unInit();
mqttc:disconnect()
log.info("mqttTask", "mqtt loop")
sys.wait(5000) -- 等待一小会, 免得疯狂重连
end
end)
return mqttTask;
mqttInMsg.lua
接收数据
代码语言:javascript复制local mqttInMsg = {}
_G.sys = require("sys")
local mqttOutMsg = require "mqttOutMsg"
--- MQTT客户端数据接收处理
-- @param mqttc
-- @return 处理成功返回true,处理出错返回false
-- @usage mqttInMsg.proc(mqttc)
function mqttInMsg.proc(mqttc)
local result,data
while true do
result, data = mqttc:receive(2000)
if result then
log.info("mqttc", "get message from server", data.payload or "nil", data.topic)
else
break;
end
--如果mqttOutMsg中有等待发送的数据,则立即退出本循环
if mqttOutMsg.waitForSend() then return true end
end
return result or data=="timeout"
end
return mqttInMsg;
mqttOutMsg.lua
发送数据
代码语言:javascript复制local mqttOutMsg = {}
_G.sys = require("sys")
local sendQueue = {} --接收数据缓存
local this_imei=nil;
-- MQTT
local msgQueue = {} --数据发送的消息队列
--设置imei
function mqttOutMsg.set_imei(imei)
this_imei = imei; --设置IMEI
end
--获取imei
function mqttOutMsg.get_imei()
return this_imei; --获取IMEI
end
--插入消息
--topic:发布的主题
--payload:发布的消息
--qos:消息等级 0或1或2
--retain:消息是否让服务器保留 0(不保留) 1(保留)
--restart:发送完成是否复位模块 0(不复位) 1(复位)
function mqttOutMsg.insertMsg(topic,payload,qos,retain,restart)
table.insert(msgQueue,{topic=topic,payload=payload,qos=qos,retain=retain,restart=restart})
end
--- 清空对象存储
function mqttOutMsg.unInit()
while #msgQueue>0 do
local outMsg = table.remove(msgQueue,1)
end
end
--- MQTT客户端是否有数据等待发送
-- @return 有数据等待发送返回true,否则返回false
-- @usage mqttOutMsg.waitForSend()
function mqttOutMsg.waitForSend()
return #msgQueue > 0
end
--- MQTT客户端数据发送处理
-- @param mqttClient,MQTT客户端对象
-- @return 处理成功返回true,处理出错返回false
-- @usage mqttOutMsg.proc(mqttClient)
function mqttOutMsg.proc(mqttClient)
while #msgQueue>0 do--有消息
local outMsg = table.remove(msgQueue,1)--提取一条消息
local result = mqttClient:publish(outMsg.topic,outMsg.payload,outMsg.qos,outMsg.retain)--发送
if not result then
return --发送失败返回空
else
if outMsg.restart == 1 then
rtos.reboot();
end
end
end
return true
end
return mqttOutMsg;
使用
1.把这三个文件拷贝到工程
2.根据自己的服务器修改MQTT参数
3.加载此程序文件
连接用户配置的MQTT服务器
4.接收消息
5.发送消息
在需要发送消息的文件里面请求 mqttOutMsg 文件,然后调用里面的
mqttOutMsg.insertMsg(topic,payload,qos,retain,restart) 插入数据即可.
如果在其它文件里面想知道mqtt连接状态, 请求 mqttTask 文件,然后调用 mqttTask.isReady()
结语
这节只是为后面的学习做铺垫.
关于MQTT软件的其它配置,将在后面的章节叙述.