作者: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外網連接好后板子能主動重連服務器 ,那這個程序就算完整了,
然后在環境中遇到各種現象應該都能自動的上線了... 有沒有大神知道這個問題怎么搞定, 貼個代碼看看怎么弄