Fix the problem with the more modern SDK only allowing one outstanding
connection:send at a time. Long and short of it, don't use coroutine.yield any more when serving content.
This commit is contained in:
parent
067ffdf3e5
commit
b4a2d02431
@ -78,11 +78,6 @@ A (very) simple web server written in Lua for the ESP8266 running the NodeMCU fi
|
||||
For example, if the client requests _http://2.2.2.2/foo.lua?color=red_ then the server will execute the function
|
||||
in your Lua script _foo.lua_ and pass in _connection_ and _args_, where _args.color = "red"_.
|
||||
|
||||
If you are going to be sending lots (as in over a KB) of data in your script, you should yield the thread/coroutine
|
||||
every now and then in order to avoid overflowing the send buffer in the microcontroller. Use:
|
||||
|
||||
coroutine.yield()
|
||||
|
||||
Look at the included example scripts for more ideas.
|
||||
|
||||
### Example: Garage door opener
|
||||
|
||||
@ -2,7 +2,6 @@ return function (connection, req, args)
|
||||
connection:send("HTTP/1.0 200 OK\r\nContent-Type: text/html\r\nCache-Control: private, no-store\r\n\r\n")
|
||||
connection:send('<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><title>Server File Listing</title></head>')
|
||||
connection:send('<body>')
|
||||
coroutine.yield()
|
||||
connection:send('<h1>Server File Listing</h1>')
|
||||
|
||||
local remaining, used, total=file.fsinfo()
|
||||
@ -20,8 +19,6 @@ return function (connection, req, args)
|
||||
if isHttpFile then
|
||||
local url = string.match(name, ".*/(.*)")
|
||||
connection:send(' <li><a href="' .. url .. '">' .. url .. "</a> (" .. size .. " bytes)</li>\n")
|
||||
-- this list could be very long, so we'll yield in order to avoid overflowing the send buffer.
|
||||
coroutine.yield()
|
||||
end
|
||||
end
|
||||
connection:send("</ul>\n")
|
||||
|
||||
@ -20,7 +20,6 @@ return function (connection, req, args)
|
||||
if chunk == nil then
|
||||
continue = false
|
||||
else
|
||||
coroutine.yield()
|
||||
connection:send(chunk)
|
||||
bytesSent = bytesSent + #chunk
|
||||
chunk = nil
|
||||
|
||||
@ -16,6 +16,34 @@ return function (port)
|
||||
|
||||
local allowStatic = {GET=true, HEAD=true, POST=false, PUT=false, DELETE=false, TRACE=false, OPTIONS=false, CONNECT=false, PATCH=false}
|
||||
|
||||
local function startServing(fileServeFunction, connection, req, args)
|
||||
local bufferedConnection = {}
|
||||
connectionThread = coroutine.create(function(fileServeFunction, connection, req, args)
|
||||
fileServeFunction(connection, req, args)
|
||||
connection:flush()
|
||||
end)
|
||||
function bufferedConnection:flush()
|
||||
connection:send(table.concat(self.data, ""))
|
||||
self.data = {}
|
||||
self.size = 0
|
||||
end
|
||||
function bufferedConnection:send(payload)
|
||||
local l = payload:len()
|
||||
if l + self.size > 1400 then
|
||||
self:flush()
|
||||
coroutine.yield()
|
||||
end
|
||||
table.insert(self.data, payload)
|
||||
self.size = self.size + l
|
||||
end
|
||||
bufferedConnection.size = 0
|
||||
bufferedConnection.data = {}
|
||||
local status, err = coroutine.resume(connectionThread, fileServeFunction, bufferedConnection, req, args)
|
||||
if not status then
|
||||
print(err)
|
||||
end
|
||||
end
|
||||
|
||||
local function onRequest(connection, req)
|
||||
collectgarbage()
|
||||
local method = req.method
|
||||
@ -59,8 +87,7 @@ return function (port)
|
||||
end
|
||||
end
|
||||
end
|
||||
connectionThread = coroutine.create(fileServeFunction)
|
||||
coroutine.resume(connectionThread, connection, req, uri.args)
|
||||
startServing(fileServeFunction, connection, req, uri.args)
|
||||
end
|
||||
|
||||
local function onReceive(connection, payload)
|
||||
@ -89,8 +116,7 @@ return function (port)
|
||||
else
|
||||
args = {code = 400, errorString = "Bad Request"}
|
||||
end
|
||||
connectionThread = coroutine.create(fileServeFunction)
|
||||
coroutine.resume(connectionThread, connection, req, args)
|
||||
startServing(fileServeFunction, connection, req, args)
|
||||
end
|
||||
end
|
||||
|
||||
@ -100,7 +126,10 @@ return function (port)
|
||||
local connectionThreadStatus = coroutine.status(connectionThread)
|
||||
if connectionThreadStatus == "suspended" then
|
||||
-- Not finished sending file, resume.
|
||||
coroutine.resume(connectionThread)
|
||||
local status, err = coroutine.resume(connectionThread)
|
||||
if not status then
|
||||
print(err)
|
||||
end
|
||||
elseif connectionThreadStatus == "dead" then
|
||||
-- We're done sending file.
|
||||
connection:close()
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user