如何使用新SDK(NodeMCU)发送多个数据(conn:send())

时间:2016-03-18 08:06:39

标签: html sockets lua esp8266 nodemcu

我一直在阅读NodeMCU文档以及关于SDK更改的几个已关闭的问题,这些问题以前允许发送多个数据流(就像排队的net.socket:send一样)。

这里似乎发生了巨大的争论(#730)和那里(#993)甚至在这里(#999)。但是,我没有找到任何令人信服的网络服务器代码示例,它允许我读取多个html文件(例如head.htmlbody.html)来显示页面。以下是我试图改编的TerryE的例子,但没有成功:

srv=net.createServer(net.TCP)
srv:listen(80,function(conn)
    conn:on ("receive", function(sck, req)
        local response = {}

        local f = file.open("head.html","r")
        if f ~= nil then
            response[#response+1] = file.read()
            file.close()
        end

        local f = file.open("body.html","r")
        if f ~= nil then
            response[#response+1] = file.read()
            file.close()
        end

        local function sender (sck)
            if #response>0 then sck:send(table.remove(response,1))
            else sck:close()
            end
        end
        sck:on("sent", sender)
        sender(sck)
    end )
end )

当连接到ESP8266时,什么都没有加载,我从lua终端没有错误。

要获取您的信息,head.html包含:

<html>
<head>
</head>

body.html包含:

<body>
<h1>Hello World</h1>
</body>
</html>

我是NodeMCU的新手,请宽容。

2 个答案:

答案 0 :(得分:3)

这是我的解决方案,不使用表格,节省了一些内存:

- (void)setMyMutableArray:(NSMutableArray *)myMutableArray

这是为了提供单个文件:

function Sendfile(sck, filename, sentCallback)
    if not file.open(filename, "r") then
        sck:close()
        return
    end
    local function sendChunk()
        local line = file.read(512)
        if line then 
            sck:send(line, sendChunk) 
        else
            file.close()
            collectgarbage()
            if sentCallback then
                sentCallback()
            else
                sck:close()
            end
        end
    end
    sendChunk()
end


srv = net.createServer(net.TCP)
srv:listen(80, function(conn)
    conn:on("receive", function(sck, req)
        sck:send("HTTP/1.1 200 OK\r\n" ..
            "Server: NodeMCU on ESP8266\r\n" ..
            "Content-Type: text/html; charset=UTF-8\r\n\r\n", 
            function()
                Sendfile(sck, "head.html", function() Sendfile(sck, "body.html") end)
            end)        
    end)
end)

答案 1 :(得分:1)

感谢您的回复。我实际上添加了你提到的标题,我不知道这是必要的,我还删除了sck函数中的sender参数。我的第一个代码实际上正在运行,我上次不知道出了什么问题。

无论如何,它帮助我理解发生了什么:以下代码似乎连接response数组,因为套接字的事件sent回调sender函数({{ 1}})

sck:on("sent", sender)

实际上,sck:send(table.remove(response,1)) 返回数组的第一项,并删除该数组的这一项。多次调用此行可以逐项读取它。

为简单起见,以下是能够提供多个文件的简单网络服务器的代码:

table.remove(array, 1)

此示例取自此instructables并已修复以使用新SDK(不允许多个:再发送)。如果此代码存在一些问题,请与我们联系。

我不知道文件的大小限制是多少。不过,我设法在header = "HTTP/1.0 200 OK\r\nServer: NodeMCU on ESP8266\r\nContent-Type: text/html\r\n\r\n" srv=net.createServer(net.TCP) srv:listen(80,function(conn) conn:on ("receive", function(sck, req) local response = {header} tgtfile = string.sub(req,string.find(req,"GET /") +5,string.find(req,"HTTP/") -2 ) if tgtfile == "" then tgtfile = "index.htm" end local f = file.open(tgtfile,"r") if f ~= nil then response[#response+1] = file.read() file.close() else response[#response+1] = "<html>" response[#response+1] = tgtfile.." not Found - 404 error." response[#response+1] = "<a href='index.htm'>Home</a>" end collectgarbage() f = nil tgtfile = nil local function sender () if #response>0 then sck:send(table.remove(response,1)) else sck:close() end end sck:on("sent", sender) sender() end) end) 变量附加超过2Ko并立即发送它而没有任何问题。