NodeMCU HTTP服务器停止响应 [英] NodeMCU HTTP server stops responding

查看:139
本文介绍了NodeMCU HTTP服务器停止响应的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用NodeMCU制作一个简单的HTTP服务器.我启动nodeMCU,然后将其连接到wifi,然后运行以下程序.我可以从浏览器连接到服务器.如果我继续重新加载页面,它将永远有效,但是当我停止发送请求一两分钟时,服务器将以某种方式停止运行.这意味着,当我重新加载页面时,nodeMCU不会接收任何数据(也无法返回任何数据).

I'm trying to make a simple HTTP server with NodeMCU. I start up nodeMCU then connect it to the wifi and then run the program below. I can connect to the server from my browser. If I keep on reloading the page it would work forever, but when I stop sending requests for a minute or two, the server will somehow stop functioning. Which means, when I reload page nodeMCU does not receive any data (and cannot return any data back).

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)

我做了一些事情:

  • 我没有添加任何链接,从而阻止了浏览器请求favicon.
  • 我将非活动客户端的超时设置为1,以防止浏览器长时间加载(浏览器一直加载直到超时).
  • 我更新了代码以发送一些HTTP标头.
  • 我尝试在每次连接后关闭和打开服务器(不好,因为如果您继续进行连接,即使没有此修复程序,它也永远不会停止工作).
  • 我在StackOverflow上的答案中建议添加conn:close().
  • I have stopped the browser from requesting favicon by adding the link to nothing.
  • I set the timeout for inactive client to 1 to prevent the browser from loading for a long time (the browser keeps on loading until timeout).
  • I updated my code to send some HTTP headers.
  • I tried closing and opening the server after each connection (no good because if you keep on doing connections it will never stop working even without this fix).
  • I added conn:close() as suggested by an answer here on StackOverflow.

我正在运行预编译的固件0.9.6-dev_20150704整数.

I'm running precompiled firmware 0.9.6-dev_20150704 integer.

推荐答案

首先,您不应该使用那些旧的0.9.x二进制文件.它们不再受支持,并且包含许多错误.从dev(1.5.1)或master(1.4)分支构建自定义固件:

First of all, you shouldn't use those old 0.9.x binaries. They're no longer supported and contain lots of bugs. Build a custom firmware from the dev (1.5.1) or master (1.4) branch: http://nodemcu.readthedocs.io/en/dev/en/build/.

使用SDK的> 1.0版本(如果从当前分支构建,这就是您得到的)conn:send是完全异步的,即,您不能连续多次调用它.另外,您不能在conn:send()之后立即调用conn:close(),因为套接字可能在send()完成之前被关闭.相反,您可以侦听sent事件并在其回调中关闭套接字.考虑到这一点,您的代码可以在最新的固件上正常工作.

With version >1.0 of the SDK (this is what you get if you build from current branches) conn:send is fully asynchronous i.e. you can't call it multiple consecutive times. Also, you must not call conn:close() right after conn:send() as the socket would possibly get closed before send() is finished. Instead you can listen to the sent event and close the socket in its callback. Your code works fine on an up-to-date firmware if you consider this.

NodeMCU API中记录了一种更优雅的异步发送方式socket:send() 的文档.但是,该方法使用了更多的堆,对于像您这样的数据很少的简单情况来说并不必要.

A more elegant way of asynchronous sending is documented in the NodeMCU API docs for socket:send(). However, that method uses more heap and is not necessary for simple cases with little data like yours.

因此,这是on("sent")的完整示例.请注意,我将图标图标更改为外部资源.如果您使用"/",浏览器仍然会对您的ESP8266发出额外的请求.

So, here's the full example with on("sent"). Note that I changed the favicon to an external resource. If you use "/" the browser still issues an extra request against your 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服务器停止响应的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆