如何使用新的 SDK (NodeMCU) 发送多个数据 (conn:send())
How to send multiple data (conn:send()) with the new SDK (NodeMCU)
我一直在阅读 NodeMCU 文档和几个关于 SDK 更改的已解决问题,这些 SDK 以前允许发送多个数据流(就像排队的 net.socket:send)。
这里似乎引发了一场激烈的争论 (#730) and there (#993) or even here (#999)。但是,我没有找到任何令人信服的网络服务器代码示例,允许我读取多个 html 文件(例如 head.html
和 body.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,请多多包涵
感谢您的回复。我实际上添加了你提到的 header,我不知道那是必要的,我还删除了 sender
函数中的 sck
参数。我的第一个代码居然能用,我不知道上次哪里出了问题。
无论如何,它帮助我理解了发生了什么:下面的代码似乎连接了 response
数组,因为套接字的事件 sent
回调了 sender
函数( sck:on("sent", sender)
)
sck:send(table.remove(response,1))
其实就是table.remove(array, 1)
returns数组的第一项,并去掉数组的这一项。多次调用此行具有逐项阅读它的效果。
为了简单起见,这里是一个简单网络服务器的代码,能够提供多个文件:
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)
此示例取自此 instructables 并已修复以使用新的 SDK(不再允许多个 :send)。如果此代码有问题,请告诉我。
虽然我不知道文件的大小限制是多少。尽管如此,我设法将超过 2Ko 附加到 response
变量并立即发送它,没有任何问题。
这是我不使用表格的解决方案,节省了一些内存:
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)
这是为单个文件提供服务:
function Sendfile(client, filename)
if file.open(filename, "r") then
local function sendChunk()
local line = file.read(512)
if line then
client:send(line, sendChunk)
else
file.close()
client:close()
collectgarbage()
end
end
client: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", sendChunk)
else
client:send("HTTP/1.0 404 Not Found\r\n\r\nPage not found")
client:close()
end
end
srv = net.createServer(net.TCP)
srv:listen(80, function(conn)
conn:on ("receive", function(client, request)
local path = string.match(request, "GET /(.+) HTTP")
if path == "" then path = "index.htm" end
Sendfile(client, path)
end)
end)
我一直在阅读 NodeMCU 文档和几个关于 SDK 更改的已解决问题,这些 SDK 以前允许发送多个数据流(就像排队的 net.socket:send)。
这里似乎引发了一场激烈的争论 (#730) and there (#993) or even here (#999)。但是,我没有找到任何令人信服的网络服务器代码示例,允许我读取多个 html 文件(例如 head.html
和 body.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,请多多包涵
感谢您的回复。我实际上添加了你提到的 header,我不知道那是必要的,我还删除了 sender
函数中的 sck
参数。我的第一个代码居然能用,我不知道上次哪里出了问题。
无论如何,它帮助我理解了发生了什么:下面的代码似乎连接了 response
数组,因为套接字的事件 sent
回调了 sender
函数( sck:on("sent", sender)
)
sck:send(table.remove(response,1))
其实就是table.remove(array, 1)
returns数组的第一项,并去掉数组的这一项。多次调用此行具有逐项阅读它的效果。
为了简单起见,这里是一个简单网络服务器的代码,能够提供多个文件:
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)
此示例取自此 instructables 并已修复以使用新的 SDK(不再允许多个 :send)。如果此代码有问题,请告诉我。
虽然我不知道文件的大小限制是多少。尽管如此,我设法将超过 2Ko 附加到 response
变量并立即发送它,没有任何问题。
这是我不使用表格的解决方案,节省了一些内存:
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)
这是为单个文件提供服务:
function Sendfile(client, filename)
if file.open(filename, "r") then
local function sendChunk()
local line = file.read(512)
if line then
client:send(line, sendChunk)
else
file.close()
client:close()
collectgarbage()
end
end
client: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", sendChunk)
else
client:send("HTTP/1.0 404 Not Found\r\n\r\nPage not found")
client:close()
end
end
srv = net.createServer(net.TCP)
srv:listen(80, function(conn)
conn:on ("receive", function(client, request)
local path = string.match(request, "GET /(.+) HTTP")
if path == "" then path = "index.htm" end
Sendfile(client, path)
end)
end)