DomingoSL
DomingoSL

Reputation: 15494

NodeMCU webserver closing connection after first send?

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?

Upvotes: 1

Views: 1548

Answers (2)

Marcel Stör
Marcel Stör

Reputation: 23535

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)

Upvotes: 1

seblucas
seblucas

Reputation: 863

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

Upvotes: 1

Related Questions