ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

3.4-Air302(NB-IOT)-网络通信-MQTT通信(本机安装MQTT+花生壳映射),MQTT文件封装

2020-12-29 06:01:05  阅读:300  来源: 互联网

标签:end -- Air302 MQTT 花生壳 return mqttOutMsg local


<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>

<iframe frameborder="0" height="1500" name="ifd" scrolling="auto" src="https://mnifdv.cn/resource/cnblogs/Learn-NB-IOT-Air302-ForLua" width="100%"></iframe>

说明

 

这节测试一下模组连接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服务器,和轮训发送和接收函数
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 接收数据
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 发送数据
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软件的其它配置,将在后面的章节叙述.

 

 

 

 

 

 

标签:end,--,Air302,MQTT,花生壳,return,mqttOutMsg,local
来源: https://www.cnblogs.com/yangfengwu/p/14204583.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有