Browse Source

aliyun:添加可以掉电重连的逻辑
main:添加根据掉电不消失的kv文件区来储存的deviceSecret,clientid,deviceToken来判断是进行正常连接还是掉电重连的逻辑

zhaihaoyu 2 years ago
parent
commit
a82989eade
2 changed files with 119 additions and 12 deletions
  1. 65 11
      demo/aliyun/main.lua
  2. 54 1
      script/libs/aliyun.lua

+ 65 - 11
demo/aliyun/main.lua

@@ -5,12 +5,12 @@ require "aliyun"
 
 --根据自己的服务器修改以下参数
 tPara = {
- Registration = false,           --是否是预注册 已预注册为false  true or false,
- DeviceName = "", --设备名称
- ProductKey = "",     --产品key
- ProductSecret = "",             --产品secret
+ Registration = true,           --是否是预注册 已预注册为false  true or false,
+ DeviceName = "861551056421746", --设备名称
+ ProductKey = "ht6f7kmyFFQ",     --产品key
+ ProductSecret = "dAmJgeQyBe57AkGM",             --产品secret
  DeviceSecret = "", --设备secret
- InstanceId = "iot-你的id",   --如果没有注册需要填写实例id,在实例详情页面
+ InstanceId = "iot-06z00bm5n8dzc26",   --如果没有注册需要填写实例id,在实例详情页面
  --新版已经合并, 没有了地域, 1883同时兼容加密和非加密通信,非加密会下线  阿里云资料:https://help.aliyun.com/document_detail/147356.htm?spm=a2c4g.73742.0.0.4782214ch6jkXb#section-rtu-6kn-kru
  mqtt_port = 1883,                 --mqtt端口
  mqtt_isssl = true,                --是否使用ssl加密连接,true为无证书最简单的加密
@@ -59,8 +59,32 @@ local function connectCbFnc(result)
         --订阅主题
         --根据自己的项目需要订阅主题,下面注释掉的一行代码中的主题是非法的,所以不能打开,一旦打开,会导致订阅失败
         -- aliyun.subscribe("/"..tPara.ProductKey.."/"..tPara.DeviceName.."/user/ceshi",1)
-        --可使用的返回值
-        -- log.info("获取的",aliyun.getDeviceSecret(),aliyun.getClientid(),aliyun.getDeviceToken())
+        
+        --使用掉电不消失的kv文件区来储存的deviceSecret,deviceToken
+        local used = fskv.get("deviceSecret")
+        local total = fskv.get("deviceToken")
+        local cid = fskv.get("clientid")
+        --储存到kv分区的返回值
+        -- log.info("kv分区的返回值",used,total,cid)
+
+        local Secret = aliyun.getDeviceSecret()
+        local Token = aliyun.getDeviceToken()
+        local Clid = aliyun.getClientid()
+        if not tPara.Registration then
+            if Secret == nil then
+                log.info("掉电重连")
+            else
+                fskv.set("deviceSecret",aliyun.getDeviceSecret())
+            end
+        else
+            if Token == nil and Clid == nil then
+                log.info("掉电重连")
+            else
+                fskv.set("deviceToken",aliyun.getDeviceToken())
+                fskv.set("clientid",aliyun.getClientid())
+            end
+        end
+
         --注册数据接收的处理函数
         aliyun.on("receive",rcvCbFnc)
         --PUBLISH消息测试
@@ -70,10 +94,40 @@ end
 
 aliyun.on("connect",connectCbFnc)
 
-
-aliyun.setup(tPara)
-
-
+--根据掉电不消失的kv文件区来储存的deviceSecret,clientid,deviceToken来判断是进行正常连接还是掉电重连
+sys.taskInit(function()
+    fskv.init()
+    fskv.set("DeviceName",tPara.DeviceName)
+    local name = fskv.get("DeviceName")
+    local used = fskv.get("deviceSecret")
+    local total = fskv.get("deviceToken")
+    local cid = fskv.get("clientid")
+    local host = tPara.InstanceId..".mqtt.iothub.aliyuncs.com"
+    --判断是否是同一DeviceName,不是的话就重新连接
+    if name == tPara.DeviceName then
+        -- fskv.del("deviceSecret")
+        if not tPara.Registration then
+            if used == nil then
+                aliyun.setup(tPara)
+            else
+                aliyun.clientGetDirectDataTask(name,tPara.ProductKey,host,tPara.mqtt_port,tPara.mqtt_isssl,tPara.Registration,used,total,cid)
+            end
+        else
+            if total == nil and cid == nil then
+                aliyun.setup(tPara)
+            else
+                aliyun.clientGetDirectDataTask(name,tPara.ProductKey,host,tPara.mqtt_port,tPara.mqtt_isssl,tPara.Registration,used,total,cid)
+            end
+        end
+    else
+        fskv.del("deviceToken")
+        fskv.del("clientid")
+        fskv.del("DeviceName")
+        fskv.del("deviceSecret")
+        --删除kv区的数据,重新建立连接
+        aliyun.setup(tPara)
+    end
+end)
 
 
 -- 用户代码已结束---------------------------------------------

+ 54 - 1
script/libs/aliyun.lua

@@ -156,7 +156,7 @@ local function clientEncryptionTask(Registration,DeviceName,ProductKey,ProductSe
             UserName = DeviceName.."&"..ProductKey
             local content = "deviceName"..DeviceName.."productKey"..ProductKey.."random"..tm
             PassWord = crypto.hmac_md5(content,ProductSecret)
-    
+            
             local mqttClient = mqtt.create(nil,mqtt_host,mqtt_port,mqtt_isssl)  --客户端创建
             mqttClient:auth(ClientId,UserName,PassWord) --三元组配置
             mqttClient:on(function(mqtt_client, event, data, payload)  --mqtt回调注册
@@ -271,6 +271,59 @@ function confiDentialTask(DeviceName,ProductKey,DeviceSecret,mqtt_host,mqtt_port
             local client_id,user_name,password = iotauth.aliyun(ProductKey,DeviceName,DeviceSecret)
             mqttc = mqtt.create(nil,mqtt_host, mqtt_port,mqtt_isssl)  --mqtt客户端创建
             mqttc:auth(client_id,user_name,password) --mqtt三元组配置
+
+
+            mqttc:keepalive(30) -- 默认值240s
+            mqttc:autoreconn(true, 3000) -- 自动重连机制
+            mqttc:connect()
+            mqttc:on(mqtt_cbevent)  --mqtt回调注册
+
+            local conres = sys.waitUntil("mqtt_conack",30000)
+            if mqttc:ready() and conres then
+                -- if connectCb then connectCb(true,ProductKey,DeviceName) end
+                -- if EvtCb["connect"] then EvtCb["connect"](true) end
+
+                local result,prompt = procSubscribe(mqttc)
+                if result then
+                    while true do
+                        procSend(mqttc)
+                    end
+                end
+
+                -- if connectCb then connectCb(false,ProductKey,DeviceName) end
+                -- if EvtCb["connect"] then EvtCb["connect"](false) end
+            end
+
+        else
+            --进入飞行模式,20秒之后,退出飞行模式
+            mobile.flymode(0,true)
+            sys.wait(20000)
+            mobile.flymode(0,false)
+        end
+    end)
+end
+
+
+--正常连接 预注册一型一密获取DeviceSecret后就是正常的一机一密连接   
+function aliyun.clientGetDirectDataTask(DeviceName,ProductKey,mqtt_host,mqtt_port,mqtt_isssl,Registration,DeviceSecret,deviceToken,cid)
+    sys.taskInit(function()
+        if mobile.status() == 0 then
+            sys.waitUntil("IP_READY",30000)
+        end
+        if mobile.status() == 1 then
+            if not Registration then
+                local client_id,user_name,password = iotauth.aliyun(ProductKey,DeviceName,DeviceSecret)
+                mqttc = mqtt.create(nil,mqtt_host, mqtt_port,mqtt_isssl)  --mqtt客户端创建
+                mqttc:auth(client_id,user_name,password) --mqtt三元组配置
+            else
+                local clientId = cid.."|securemode=-2,authType=connwl|"
+    
+                local client_id,user_name,password = iotauth.aliyun(ProductKey,DeviceName,deviceToken)
+                mqttc = mqtt.create(nil,mqtt_host, mqtt_port,mqtt_isssl)  --mqtt客户端创建
+        
+                mqttc:auth(clientId,user_name,deviceToken) --mqtt三元组配置
+            end
+
             mqttc:keepalive(30) -- 默认值240s
             mqttc:autoreconn(true, 3000) -- 自动重连机制
             mqttc:connect()