Merge pull request #43 from pjsg/master

Fix the problem with the more modern SDK only allowing one outstanding connection:send
This commit is contained in:
Marcos 2015-11-29 10:16:11 -06:00
commit 3eecd76908
5 changed files with 53 additions and 18 deletions

View File

@ -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

View File

@ -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")

View File

@ -4,14 +4,16 @@ local function sendHeader(connection)
end
local function sendAttr(connection, attr, val)
if val then
connection:send("<li><b>".. attr .. ":</b> " .. val .. "<br></li>\n")
end
end
return function (connection, req, args)
collectgarbage()
sendHeader(connection)
connection:send('<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><title>A Lua script sample</title></head><body><h1>Node info</h1><ul>')
majorVer, minorVer, devVer, chipid, flashid, flashsize, flashmode, flashspeed = node.info();
local majorVer, minorVer, devVer, chipid, flashid, flashsize, flashmode, flashspeed = node.info();
sendAttr(connection, "NodeMCU version" , majorVer.."."..minorVer.."."..devVer)
sendAttr(connection, "chipid" , chipid)
sendAttr(connection, "flashid" , flashid)

View File

@ -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

View File

@ -16,6 +16,47 @@ 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, bconnection, req, args)
fileServeFunction(bconnection, req, args)
if not bconnection:flush() then
connection:close()
connectionThread = nil
end
end)
function bufferedConnection:flush()
if self.size > 0 then
connection:send(table.concat(self.data, ""))
self.data = {}
self.size = 0
return true
end
return false
end
function bufferedConnection:send(payload)
local l = payload:len()
if l + self.size > 1000 then
if self:flush() then
coroutine.yield()
end
end
if l > 800 then
connection:send(payload)
coroutine.yield()
else
table.insert(self.data, payload)
self.size = self.size + l
end
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 +100,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 +129,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 +139,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()