Send entire html code with client:send() in Nodemcu Esp8266 lua programming

旧时模样 提交于 2019-12-25 00:29:26

问题


I created a lua file that implements a 2relay module to control a rolling shutter through a website.
I followed the led_webserver example and I extended my code from there.
I tried so many ways to send a full html page with the function client:send(),
but it doesn't seem to work.


It's a page I developed myself and it works on the pc but I couldn't find an easy way to send it.
I declare a local variable (for example test) that contains all the html code and then i put it as parameter in `client:send(test).
Does someone know another way to do so?


回答1:


The TCP stack on the eps8266 doesn't support streaming across IP packets. Each send can be up to one full IP packet but longer than that and you have send them packet by packet using the soc:on("sent",callback). See the nodeMCU Unofficial FAQ for more discussion of this.




回答2:


Other posters have given a lot of good information, but I don't think there was a good specific solution to this problem given yet, even in the unofficial FAQ.

To send large static files, you can load them from flash and send them in chunks, using callbacks. As other people have mentioned, there is a limit to how much can be sent with a single call. And multiple send calls in a single callback may not be processed as you expect them to, and may take too much memory. Here is a short example loading and sending a file in chunks:

local idx = 0 --keep track of where we are in the file
local fname = "index.html"

function nextChunk(c) --open file, read a chunk, and send it!
      file.open(fname)
      file.seek("set", idx)
      local str = file.read(500)
      if not str then return end --no more to send. 
      c:send(str)
      idx = idx + 500
      file.close() --close the file to let other callbacks use the filesystem
end
client:on("sent", nextChunk) --every time we send a chunk, start the next one!
nextChunk(client) --send the first chunk. 

or, using coroutines and a timer, we can make it more flexible:

local ready = true --represents whether we are ready to send again
client:on("sent", function() ready=true end) --we are ready after sending the previous chunk is finished.

local function sendFile(fname)
    local idx=0 --keep track of where we are in the file
    while true do
        file.open(fname)
        file.seek("set", idx)
        local str = file.read(500)
        if not str then return end --no more to send. 
        c:send(str)
        ready=false --we have sent something. we are no longer ready.
        idx = idx + 500
        file.close() --close the file to let other callbacks use the filesystem
        coroutine.yield() --give up control to the caller
    end
end

local sendThread = coroutine.create(sendFile)
tmr.alarm(0, 100, 1, function() --make a repeating alarm that will send the file chunk-by-chunk
    if ready then coroutine.resume(sendThread, "index.html") end
    if coroutine.status(sendThread) == "dead" then tmr.stop(0) end --stop when we are done
end)



回答3:


You can use the following:

    buf = "<h1> ESP8266 Web Server</h1>";
    buf = buf.."<h2>Subtitle</h2>";
    client:send(buf);



回答4:


Sending more than a couple hundred bytes in one call fails more often than not. Also realize that multiple successive calls to send within the same lua chunk are queued and performed asynchronously after the chunk returns -- this consumes impractical amounts of memory.

So building a page of any complexity at all with runtime values concatenated in is problematic. A more rational approach is for the ESP8266 to just return data as JSON, and serve the fancy pages from a PC, with embedded script to query the ESP and fold the data into the page.




回答5:


I found a simple solution for this. I had to send a large file containing text and I used the following code for it:

    file.open("example.txt","r") 
    for counter=1, numboflinesinfile-1 do
    client:send(file.readline() .. "<br>");  
    end           
    file.close()

counter is just a counting variable numberoflinesinfile is the number of lines you want to send.

Not a clean solution and maybe violating all program rules but working as a charm.



来源:https://stackoverflow.com/questions/30544301/send-entire-html-code-with-clientsend-in-nodemcu-esp8266-lua-programming

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!