【问题标题】:NodeMCU webserver closing connection after first send?第一次发送后NodeMCU网络服务器关闭连接?
【发布时间】:2023-03-11 03:15:01
【问题描述】:

我在我的 ESP-12 上运行了一个带有 nodemcu 固件的小型 Web 服务器:

sv=net.createServer(net.TCP,10)

sv:listen(80,function(c)

    c:on("receive", function(c, pl)

        if(string.find(pl,"GET / ")) then
            print("Asking for index")
            c:send("Line 1")
            c:send("Line 2")
            c:send("Line 3")
            c:close()
        end

    end)
  c:on("sent",function(conn) 
    print("sended something...")
  end)
end)

似乎我的连接在第一次发送后关闭,在我的浏览器中我只看到“第 1 行”文本,第 2 a 3 行没有出现,在我的串行控制台中我只看到“发送的东西”文本有一次,即使评论关闭语句并让连接超时也不会改变行为。我在这里错过了什么?

【问题讨论】:

    标签: lua nodemcu


    【解决方案1】:

    我认为您不能多次使用 send。每当我使用我的 ESP8266 作为服务器时,我都会使用缓冲区变量:

    sv=net.createServer(net.TCP,10)
    -- 'c' -> connection, 'pl' -> payload
    sv:listen(80,function(c)
    
        c:on("receive", function(c, pl)
    
            if(string.find(pl,"GET / ")) then
                print("Asking for index")
                local buffer = ""
                buffer = buffer.."Line 1"
                buffer = buffer.."Line 2"
                buffer = buffer.."Line 3"
                c:send(buffer)
                c:close()
            end
    
        end)
        c:on("sent",function(c)
            print("sended something...")
        end)
    end)
    

    编辑:再次阅读文档后,send 可以接受另一个带有回调函数的参数,它可以用于有多个发送命令。不过没试过:(。

    编辑 2:如果要发送很长的字符串,最好使用table.concat

    【讨论】:

    • 我不久前使用了缓冲解决方案,它可以工作,但问题是如果你必须缓冲一个大文件,你就有可能超出 Ram 的风险。也许回调工作的想法,我会尝试一下。谢谢
    • 确实我应该想到这一点(我曾经遇到过问题)。我修改了答案以添加有关 table.concat 的注释
    • 这个是内存泄漏,因为回调函数重用了c。我将添加一个替代答案,相关问题请参见 stackoverflow.com/a/37379426/131929stackoverflow.com/a/36094397/131929
    【解决方案2】:

    net.socket:send() 文档提供了一个很好的示例,我在此重复。

    srv = net.createServer(net.TCP)
    
    function receiver(sck, data)
      local response = {}
    
      -- if you're sending back HTML over HTTP you'll want something like this instead
      -- local response = {"HTTP/1.0 200 OK\r\nServer: NodeMCU on ESP8266\r\nContent-Type: text/html\r\n\r\n"}
    
      response[#response + 1] = "lots of data"
      response[#response + 1] = "even more data"
      response[#response + 1] = "e.g. content read from a file"
    
      -- sends and removes the first element from the 'response' table
      local function send(localSocket)
        if #response > 0 then
          localSocket:send(table.remove(response, 1))
        else
          localSocket:close()
          response = nil
        end
      end
    
      -- triggers the send() function again once the first chunk of data was sent
      sck:on("sent", send)
    
      send(sck)
    end
    
    srv:listen(80, function(conn)
      conn:on("receive", receiver)
    end)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-12-02
      • 2021-12-23
      • 1970-01-01
      • 2019-08-30
      • 2017-01-30
      • 2019-05-18
      • 1970-01-01
      • 2012-10-21
      相关资源
      最近更新 更多