<noscript id="mmkmi"><source id="mmkmi"></source></noscript>
  • <noscript id="mmkmi"><kbd id="mmkmi"></kbd></noscript>
  • <table id="mmkmi"><source id="mmkmi"></source></table>
  • Lua開關程序有個場景無法重連上服務器

    作者:candylie520 | 更新時間:2019-09-14 | 瀏覽量:1174

    github上的程序我就不貼了, 先說現象

    問題一:斷開路由器后重連不上路由器的問題,

    init.lua程序里面的問題就是, 沒有自動重連, 所以當板子連接到wifi獲取到ip后, 主動關閉路由器, 再打開路由器就連不上wifi了, 這個解決辦法是加一句 

    wifi.sta.autoconnect(1)

    這樣每次斷開路由器后就能重新連接上路由器了

     

    問題二:先上git上貝殼的主程序

    --use sjson

    _G.cjson = sjson

    --modify DEVICEID INPUTID APIKEY

    DEVICEID = "458"

    APIKEY = "9cb78xxx9"

    INPUTID = "36"

    host = host or "www.eqytg.org"

    port = port or 8181

    LED = 5

    isConnect = false

    gpio.mode(LED,gpio.OUTPUT)

    local function run()

    local cu = net.createConnection(net.TCP)

    cu:on("receive", function(cu, c)

    print(c)

    isConnect = true

    r = cjson.decode(c)

    if r.M == "say" then

    if r.C == "play" then

    gpio.write(LED, gpio.HIGH)

    ok, played = pcall(cjson.encode, {M="say",ID=r.ID,C="LED turn on!"})

    cu:send( played.."\n" )

    end

    if r.C == "stop" then

    gpio.write(LED, gpio.LOW)

    ok, stoped = pcall(cjson.encode, {M="say",ID=r.ID,C="LED turn off!"})

    cu:send( stoped.."\n" )

    end

    end

    end)

    cu:on('disconnection',function(scu)

    cu = nil

    isConnect = false

    --停止心跳包發送定時器,5秒后重試

    tmr.stop(1)

    tmr.alarm(6, 5000, 0, run)

    end)

    cu:connect(port, host)

    ok, s = pcall(cjson.encode, {M="checkin",ID=DEVICEID,K=APIKEY})

    if ok then

    print(s)

    else

    print("failed to encode!")

    end

    if isConnect then

    cu:send(s.."\n")

    end

    tmr.alarm(1, 60000, 1, function()

    if isConnect then

    cu:send(s.."\n")

    end

    end)

    end

    run()

     

    在kaiguan.lua程序中,如果路由器關了, 會走disconnection回調, 然后重新執行run方法, 但是此時路由器還沒有開啟, 那么程序最底下的定時器1就永遠也發不出心跳包, 當然也會重連不上服務器了....

    所以為了解決這個問題, 我改了下代碼, 添加了一個看門的狗子

    改動后的代碼如下:

    --use sjson

    _G.cjson = sjson

    --modify DEVICEID INPUTID APIKEY

    DEVICEID = "1"

    APIKEY = "11111111"

    INPUTID = "36"

    --host = host or "www.eqytg.org"

    host = host or "121.42.180.30"

    port = port or 8181

    LED = 5

    isConnect = false

     

    gpio.mode(LED,gpio.OUTPUT)

    local _Me = {}

    autoTime = 1000

    hadCloseRoter = false

    count = 1

    function watch()

    --此定時間用來判斷ip是否被中斷過,因為當直接路由器斷電后, wifi會自動連接,但是不會走自動登錄服務器,

    tmr.alarm(2, autoTime, 1, function()

    print("zk,"..count)

    count = count+1

    if wifi.sta.getip() == nil then

    --記錄已經有過wifi斷線 那就把循環次數調低到1分鐘檢測一次ip是否有獲取到

    autoTime = 6000

    --關閉定時器節約資源

    tmr.stop(1)

    --如果是首次記錄到斷線,就重新按照新時間記錄定時器

    if hadCloseRoter == false then

    tmr.stop(2)

    --記錄下已經有過斷開wifi的記錄

    hadCloseRoter = true

    print("dog watch Time set 6s once")

    watch()

    end

    else

    --如果記錄過有wifi斷線 并且當前ip已經獲取到了,連上了路由器,就重新走run方法

    if hadCloseRoter then

    print("check had close wifi link, now need auto link service,and dog watch time set 1s once")

    isConnect = false

    hadCloseRoter = false

    autoTime = 1000

    tmr.stop(1)

    tmr.stop(2)

    cu = nil

    watch()

    run()

    end

    end

    end)

    end

    watch()

     

    function run()

    --獲取cu

    local cu = net.createConnection(net.TCP)

    --收到服務器消息的回調

    cu:on("receive", function(cu, c)

    print("zk,receive\n")

    print(c)

    isConnect = true

    r = cjson.decode(c)

    if r.M == "say" then

    if r.C == "play" then

    gpio.write(LED, gpio.HIGH)

    ok, played = pcall(cjson.encode, {M="say",ID=r.ID,C="LED turn on!"})

    cu:send( played.."\n" )

    end

    if r.C == "stop" then

    gpio.write(LED, gpio.LOW)

    ok, stoped = pcall(cjson.encode, {M="say",ID=r.ID,C="LED turn off!"})

    cu:send( stoped.."\n" )

    end

    end

    end)

    --服務器斷開連接的回調 如果是直接路由器斷電會走此方法, 但是路由器的wlan斷了不會走此方法

    cu:on('disconnection',function(scu)

    cu = nil

    isConnect = false

    --停止心跳包發送定時器,5秒后重試

    print("zk,disconnection")

    tmr.stop(1)

    tmr.alarm(6, 3000, 0, run)

    end)

    --連接服務器 連接成功后會在Reciver中返回:{"M":"WELCOME TO BIGIOT"} 并且isConnet設置為true

    cu:connect(port, host)

     

    --encode密鑰ID

    ok, s = pcall(cjson.encode, {M="checkin",ID=DEVICEID,K=APIKEY})

    --如果密鑰ID正常就 打印密鑰ID

    if ok then

    print(s)

    else

    print("failed to encode!")

    end

     

    --發送心跳

    if isConnect then

    cu:send(s.."\n")

    end

     

    --啟動5s定時器 如果已連接就定時發送心跳

    tmr.alarm(1, 8000, 1, function()

    if isConnect then

    print("auto send headPackge")

    cu:send(s.."\n")

    else

    print("not connected ...")

    end

    end)

    end

    run()

    添加了一個定時器的方法, 由于一點不懂lua還有nodemcu的api, 就這樣搞了下, 核心邏輯是這樣的:

    連上網后每秒鐘檢測ip, 如果檢測到ip為空了就把這個定時器的時間改成每6s運行一次查詢ip, 如果檢測到ip又獲取到了,表示重連上了路由器, 這時候就再次把這個定時器的時間改為1s一次, 

    并且重新執行run方法, 所以 現在問題2就已經改好了, 每次被斷開wifi后, 重連上了就能主動連接貝殼服務器了, 但是這樣還是有問題......

     

    問題三: 當臉上貝殼后臺后, 路由器的網斷了, 這時候雖然板子連上了路由器, 也一直在執行定時器1的心跳包, 但是,這種情況是不會走disconnection回調的,

    所以造成的現象就是板子并不知道自己已經沒有外網了,還一直以為自己在線, 不斷地發心跳包, 這是沒什么卵用的,  這時候, 當路由器又連接到了外網后, 板子還是處于蒙蔽狀態

    還是以為自己在線, 也收不到disconnection回調改變自己狀態, 貝殼的服務器也是檢測不到設備在線的

     

    由于就昨天晚上研究下了lua, 還不是很懂, 所以問題3無法搞定,  目前就是 只要解決了路由器的wlan掉線后, 板子能知道自己掉線了, 然后等路由器的wlan外網連接好后板子能主動重連服務器 ,那這個程序就算完整了,

    然后在環境中遇到各種現象應該都能自動的上線了... 有沒有大神知道這個問題怎么搞定, 貼個代碼看看怎么弄

     

     

     


    評論:共3條

    caibihui163 評論于:2019-09-23 16:58:36
    發送心跳包后,貝殼服務器應有一個 響應的回復,檢測這個有沒有回復就可以知其有沒有接上貝殼了?個人觀點,我沒有具體看過!
    damahua 評論于:2019-11-29 18:03:35
    用 Arduino 寫代碼 沒這么多問題 之前用Lua 老是掉線
    不需要解釋 評論于:2020-01-29 15:16:38
    我也是這個情況,今天是2020年1月29日。求大神解決
    返回頂部
    <noscript id="mmkmi"><source id="mmkmi"></source></noscript>
  • <noscript id="mmkmi"><kbd id="mmkmi"></kbd></noscript>
  • <table id="mmkmi"><source id="mmkmi"></source></table>
  • 三上悠亚在线观看