NodeMCU HTTP 服务器停止响应
NodeMCU HTTP server stops responding
我正在尝试使用 NodeMCU 制作一个简单的 HTTP 服务器。我启动 nodeMCU,然后将其连接到 wifi,然后 运行 下面的程序。我可以从我的浏览器连接到服务器。如果我继续重新加载页面,它将永远工作,但是当我停止发送请求一两分钟时,服务器将以某种方式停止运行。这意味着,当我重新加载页面时,nodeMCU 没有收到任何数据(并且不能 return 返回任何数据)。
a=0
function receive(conn,payload)
a=a+1
print(payload)
local content="<!DOCTYPE html><html><head><link rel='shortcut icon' href='/'></head><body><h1>Hello!</h1><p>Since the start of the server " .. a .. " connections were made</p></body></html>"
local contentLength=string.len(content)
conn:send("HTTP/1.1 200 OK\r\nContent-Length:" .. contentLength .. "\r\n\r\n" .. content)
conn:close()
end
function connection(conn)
conn:on("receive",receive)
end
srv=net.createServer(net.TCP,1)
srv:listen(8080,connection)
我做过的一些事情:
- 我已通过将 link 添加为空来阻止浏览器请求网站图标。
- 我将非活动客户端的超时设置为1,以防止浏览器长时间加载(浏览器一直加载直到超时)。
- 我更新了我的代码以发送一些 HTTP headers。
- 我尝试在每次连接后关闭和打开服务器(不好,因为如果你继续连接,即使没有这个修复它也永远不会停止工作)。
- 我按照 Whosebug 上的答案的建议添加了
conn:close()
。
我是运行宁预编译固件0.9.6-dev_20150704整数.
首先,您不应该使用那些旧的 0.9.x 二进制文件。它们不再受支持并且包含很多错误。从 dev
(1.5.1) 或 master
(1.4) 分支构建自定义固件:http://nodemcu.readthedocs.io/en/dev/en/build/.
对于版本 >1.0 的 SDK(这是您从当前分支构建的版本)conn:send
是完全异步的,即您不能连续多次调用它。此外,您不能在 conn:send()
之后立即调用 conn:close()
,因为套接字可能会在 send()
完成之前关闭。相反,您可以监听 sent
事件并在其回调中关闭套接字。如果您考虑到这一点,您的代码在最新固件上运行良好。
NodeMCU API docs for socket:send()
中记录了一种更优雅的异步发送方式。但是,该方法使用更多的堆,对于像您这样数据很少的简单情况来说不是必需的。
所以,这里是 on("sent")
的完整示例。请注意,我将网站图标更改为外部资源。如果您使用“/”,浏览器仍会向您的 ESP8266 发出额外请求。
a = 0
function receive(conn, payload)
print(payload)
a = a + 1
local content="<!DOCTYPE html><html><head><link rel='icon' type='image/png' href='http://nodemcu.com/favicon.png' /></head><body><h1>Hello!</h1><p>Since the start of the server " .. a .. " connections were made</p></body></html>"
local contentLength=string.len(content)
conn:on("sent", function(sck) sck:close() end)
conn:send("HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nContent-Length:" .. contentLength .. "\r\n\r\n" .. content)
end
function connection(conn)
conn:on("receive", receive)
end
srv=net.createServer(net.TCP, 1)
srv:listen(8080, connection)
我正在尝试使用 NodeMCU 制作一个简单的 HTTP 服务器。我启动 nodeMCU,然后将其连接到 wifi,然后 运行 下面的程序。我可以从我的浏览器连接到服务器。如果我继续重新加载页面,它将永远工作,但是当我停止发送请求一两分钟时,服务器将以某种方式停止运行。这意味着,当我重新加载页面时,nodeMCU 没有收到任何数据(并且不能 return 返回任何数据)。
a=0
function receive(conn,payload)
a=a+1
print(payload)
local content="<!DOCTYPE html><html><head><link rel='shortcut icon' href='/'></head><body><h1>Hello!</h1><p>Since the start of the server " .. a .. " connections were made</p></body></html>"
local contentLength=string.len(content)
conn:send("HTTP/1.1 200 OK\r\nContent-Length:" .. contentLength .. "\r\n\r\n" .. content)
conn:close()
end
function connection(conn)
conn:on("receive",receive)
end
srv=net.createServer(net.TCP,1)
srv:listen(8080,connection)
我做过的一些事情:
- 我已通过将 link 添加为空来阻止浏览器请求网站图标。
- 我将非活动客户端的超时设置为1,以防止浏览器长时间加载(浏览器一直加载直到超时)。
- 我更新了我的代码以发送一些 HTTP headers。
- 我尝试在每次连接后关闭和打开服务器(不好,因为如果你继续连接,即使没有这个修复它也永远不会停止工作)。
- 我按照 Whosebug 上的答案的建议添加了
conn:close()
。
我是运行宁预编译固件0.9.6-dev_20150704整数.
首先,您不应该使用那些旧的 0.9.x 二进制文件。它们不再受支持并且包含很多错误。从 dev
(1.5.1) 或 master
(1.4) 分支构建自定义固件:http://nodemcu.readthedocs.io/en/dev/en/build/.
对于版本 >1.0 的 SDK(这是您从当前分支构建的版本)conn:send
是完全异步的,即您不能连续多次调用它。此外,您不能在 conn:send()
之后立即调用 conn:close()
,因为套接字可能会在 send()
完成之前关闭。相反,您可以监听 sent
事件并在其回调中关闭套接字。如果您考虑到这一点,您的代码在最新固件上运行良好。
NodeMCU API docs for socket:send()
中记录了一种更优雅的异步发送方式。但是,该方法使用更多的堆,对于像您这样数据很少的简单情况来说不是必需的。
所以,这里是 on("sent")
的完整示例。请注意,我将网站图标更改为外部资源。如果您使用“/”,浏览器仍会向您的 ESP8266 发出额外请求。
a = 0
function receive(conn, payload)
print(payload)
a = a + 1
local content="<!DOCTYPE html><html><head><link rel='icon' type='image/png' href='http://nodemcu.com/favicon.png' /></head><body><h1>Hello!</h1><p>Since the start of the server " .. a .. " connections were made</p></body></html>"
local contentLength=string.len(content)
conn:on("sent", function(sck) sck:close() end)
conn:send("HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nContent-Length:" .. contentLength .. "\r\n\r\n" .. content)
end
function connection(conn)
conn:on("receive", receive)
end
srv=net.createServer(net.TCP, 1)
srv:listen(8080, connection)