--- testSocket -- @module testSocket -- @author AIRM2M -- @license MIT -- @copyright openLuat.com -- @release 2018.10.27 require "socket" module(..., package.seeall) -- 此处的IP和端口请填上你自己的socket服务器和端口 --local ip, port, c = "116.62.220.88", "20160" local dataIp, dataTcpPort, dataUdpPort = nvm.get("dataIp"), nvm.get("dataTcpPort"), nvm.get("dataUdpPort") local macAddr = nvm.get("devId") local rfidSocketRetryInterval = nvm.get("rfidSocketRetryInterval") or 1 local rfidSocketRetryTimes = nvm.get("rfidSocketRetryTimes") or 5 local rfidSocketRetrySleep = nvm.get("rfidSocketRetrySleep") or 20 --1M ram 可用空间,超出空间,硬件会重启 local upload_packet_data_queue_max_length = 50 local upload_packet_data_queue = {} local function insert_upload_packet_data_queue(packet_data) log.info("#upload_packet_data_queue = ",#upload_packet_data_queue) if #upload_packet_data_queue >= upload_packet_data_queue_max_length then table.remove(upload_packet_data_queue, 1) end table.insert(upload_packet_data_queue, packet_data) end local function upload_packet_data( packet_data ) if not packet_data then log.error("socketTask.upload_packet_data","packet_data empty!") return false end if not dataIp then log.error("socketTask.upload_packet_data","dataIp empty!") return false end if not dataTcpPort then log.error("socketTask.upload_packet_data","dataTcpPort empty!") return false end --上传前,先进行断电检测(断电后,不再上传数据,缓存一段时间后,写入flash,等上电后再上传) local retryConnectCnt = 0 while true do while not socket.isReady() do log.info("socketTask.upload_packet_data",">>>>>>> socket is not ready, wait IP_READY_IND ...") sys.waitUntil("IP_READY_IND",300000) end local socketClient = socket.tcp() if retryConnectCnt>=rfidSocketRetryTimes then --断开socket连接 socketClient:close() log.info("socketTask.upload_packet_data",">>>>>>> retryConnectCnt>=5,link.shut,wait 20s ...") link.shut() retryConnectCnt=0 sys.wait(rfidSocketRetrySleep*1000) while not socket.isReady() do log.info("socketTask.upload_packet_data",">>>>>>> socket is not ready, wait IP_READY_IND again ...") sys.waitUntil("IP_READY_IND",300000) end socketClient = socket.tcp() end --阻塞执行socket connect动作,直至成功 if socketClient:connect(dataIp, dataTcpPort, 10) then if socketClient:send(packet_data, 10) then --断开socket连接 socketClient:close() retryConnectCnt = 0 log.info("socketTask.upload_packet_data","------> packet_data upload success <------") break else --断开socket连接 socketClient:close() retryConnectCnt = retryConnectCnt+1 log.info("socketTask.upload_packet_data",">>>>>>> socket.send failed,wait 5s ...,retryConnectCnt = ",retryConnectCnt) sys.wait(rfidSocketRetryInterval*1000) end else --断开socket连接 socketClient:close() retryConnectCnt = retryConnectCnt+1 log.info("socketTask.upload_packet_data",">>>>>>> socket.connect failed,wait 5s ...,retryConnectCnt = ",retryConnectCnt) sys.wait(rfidSocketRetryInterval*1000) end end return true end --[[ sys.taskInit( function() while true do --阻塞监听监听串口接收数据 log.info("socketTask.insert_upload_packet_data_queue",">>>>>>>>>>> waitUntil pub_msg(timeout:3600s) ...") local result, packet_data = sys.waitUntil("pub_msg",3600*1000) if result == true then local cur_time = os.time() insert_upload_packet_data_queue(packet_data) --log.info("socketTask.insert_upload_packet_data_queue",">>>>>>>> insert upload_packet_data_queue times(s):",os.time()-cur_time) else log.info("socketTask.insert_upload_packet_data_queue",">>>>>>>> wait pub_msg timeout") end end end ) ]] sys.taskInit( function() while true do --从队列逐个取出数据,并上传到服务端 if #upload_packet_data_queue > 0 then local cur_time = os.time() local packet_data = table.remove(upload_packet_data_queue, 1) --log.info("socketTask.upload_packet_data_queue",">>>>>>>> pop upload_packet_data_queue times(s):",os.time()-cur_time) if packet_data then if not upload_packet_data( packet_data ) then log.error("socketTask.upload_packet_data_queue",">>>>>>>> upload_packet_data failed!!") end end else log.info("socketTask.upload_packet_data_queue",">>>>>>>> upload_packet_data_queue empty, wait 1s ...") sys.wait(1000) end end end ) local function hex2bin( hexstr ) local str = "" for i = 1, string.len(hexstr) - 1, 2 do local doublebytestr = string.sub(hexstr, i, i+1); local n = tonumber(doublebytestr, 16); if 0 == n then str = str .. '\00' else str = str .. string.format("%c", n) end end return str end --组装待发送数据包 local function parse_packet( packet_data ) if not packet_data then return end --取imei后三个字节 if not macAddr then log.info("socketTask.parse_packet","macAddr empty!") macAddr = nvm.get("devId") return false end if #macAddr < 6 then log.info("socketTask.parse_packet","parse_packet fail,macAddr length < 6! macAddr = ",macAddr) return false end local packet_bin = string.char(0x9c)..string.char(0xbc)..string.char(0x01)..hex2bin(macAddr:sub(-6)) local length = 0 local tmp_bin = "" for key, rfid in pairs(packet_data["buf"]) do if type(rfid) == "table" then if not rfid.time then log.info("socketTask.parse_packet",">>>>>>>>> rfid.time empty! ", type(rfid)) for k, v in pairs(rfid) do log.info("socketTask.parse_packet",">>>>>>>>> rfid", "k:", k, ", v:", v) end return false end tmp_bin = tmp_bin .. hex2bin(key)..string.char(rfid.type)..string.char(rfid.status) ..string.char(rfid.rssi)..hex2bin(string.format( "%08X", rfid.time )) ..string.char(rfid.recv_count)..string.char(60)..string.char(1) else log.info("socketTask.parse_packet",">>>>>>>>> rfid error! key = ", key) return false end end packet_bin = packet_bin .. hex2bin(string.format( "%04X", tmp_bin:len())) .. tmp_bin --log.info(">>>>>>>>> sub packet_bin:sub(1, 30):toHex()", packet_bin:sub(1, 30):toHex(), ", macAddr:", macAddr) return true,packet_bin end -- 测试代码,用于发送消息给socket sys.taskInit(function() while true do --log.info("socketTask.pub_msg",">>>>>>>>>>> waitUntil pub_packet_data_renlian ") --阻塞监听监听串口接收数据 local cur_time = os.time() local result, packet_data = sys.waitUntil("pub_packet_data_renlian",300*1000) if result then --log.info("socketTask.pub_msg",">>>>>>>>> recv pub_packet_data_renlian, times(s):", os.time()-cur_time, json.encode(packet_data)) --[[ --设备解析rfid性能测试代码 local rfid_str = "" for key, rfid in pairs(packet_data["buf"]) do rfid_str = rfid_str..key.."," end log.info("socketTask.pub_msg", "timestamp:", cur_time, "rfid_str:",rfid_str) ]] cur_time = os.time() local res, parse_packet_data = parse_packet(packet_data) if res then log.info("socketTask.pub_msg",">>>>>>>>> publish pub_msg, parse_packet times(s):", os.time()-cur_time, ", parse_packet_data:sub(1, 30):toHex() = ",parse_packet_data:sub(1, 30):toHex()) --log.info("socketTask.pub_msg",", parse_packet_data:toHex() = ", parse_packet_data:toHex()) --sys.publish("pub_msg", parse_packet_data) insert_upload_packet_data_queue(parse_packet_data) else log.error("socketTask.pub_msg",">>>>>>>>> parse_packet failed!!") end else log.info("socketTask.pub_msg",">>>>>>>>> wait pub_packet_data_renlian timeout") --sys.wait(1000) end end end) sys.timerLoopStart(function() log.info("打印占用的内存:", _G.collectgarbage("count"))-- 打印占用的RAM log.info("打印可用的空间", rtos.get_fs_free_size())-- 打印剩余FALSH,单位Byte end, 10000)