1

I have an small web server running on my ESP-12 with nodemcu firmware:

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)

It seems my connection is getting closed after the first send, in my browser I only see the "line 1" text, line 2 a 3 does not appear, and in my serial console im just seeing the "sended something" text one time, even commenting the close statement and letting the connection to timeout does not change the behavior. What am I missing here?

DomingoSL
  • 14,920
  • 24
  • 99
  • 173

2 Answers2

1

I don't think that you can use send multiple times. Whenever I use one of my ESP8266 as a server I use a buffer variable :

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)

EDIT: After reading the docs again, send can take another argument with a callback function, it can maybe be used to have multiple send command. Never tried it though :(.

EDIT 2: If you have a really long string to send, it's better to use table.concat

Marcel Stör
  • 22,695
  • 19
  • 92
  • 198
seblucas
  • 825
  • 1
  • 7
  • 17
  • I used the buffer solution a while ago and it works, but the problem is if you have to buffer a large file you risk to be out of Ram. Maybe the idea of the callback work, im gonna try it. Thank you – DomingoSL Nov 22 '15 at 11:18
  • Indeed I should have thought of that (I had the problem once). I modified my answer to add a note about table.concat – seblucas Nov 22 '15 at 20:10
  • This one is leaking memory because the callback function re-uses `c`. I'll add an alternative answer, see http://stackoverflow.com/a/37379426/131929 and http://stackoverflow.com/a/36094397/131929 for related questions. – Marcel Stör Feb 12 '17 at 20:52
1

The net.socket:send() documentation provides a nice example which I repeat here.

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)
Marcel Stör
  • 22,695
  • 19
  • 92
  • 198