一不小心又拖了大半个月。
这次我们将搭建一个HTTP服务器,然后通过访问网页来控制LED灯的开关。
惯例先放上各种链接
nodemcu的wifi模块
wifi模块的AP模式
ESP8266是一个wifi模块,所以核心当然就是它的wifi功能。
nodemcu可以设置4种wifi模式,分别是STA模式wifi.STATION
,AP模式wifi.SOFTAP
,STA+AP模式wifi.STATIONAP
,还有无模式wifi.NULLMODE
。
我们先介绍AP模式,它可以开放一个热点让其他设备连接上ESP8266。
1 | cfg={} -- 声明一个cfg变量存放AP模式的配置 |
设置好之后我们就可以在WLAN列表里找到我们的热点了(不知道为什么我用电脑连不上,只能通过手机连接,好像很多人都遇到了这个问题,不过不影响我们调试,暂时先不管)。
通过wifi.ap.config()
还可以设置AP模式的加密模式之类的,具体细节可以自己看官方文档。
wifi模块的STA模式
STA模式可以让ESP8266连接到其他热点
1 | station_cfg={} -- 声明一个station_cfg变量存放STA模式的配置 |
连接到热点时就会输出ip地址
其他细节可以看官方文档里的wifi.sta.config()
如果想要同时设置AP和STA模式可以使用wifi.setmode(wifi.STATIONAP)
开启STA+AP模式
一个简单的HTTP服务器
HTTP请求
首先是官网上的示例
1 | -- a simple http server |
先把程序上传到nodemcu里,然后在串口工具里输入wifi.setmode(wifi.STATIONAP)
开启AP模式。
手机连接到热点后我们在串口工具里输入=wifi.ap.getip()
就可以获取到nodemcu服务器的ip地址,在手机浏览器中输入这个ip地址我们就能访问当nodemcu服务器。
之后串口工具中将会输出一大串字符,这是来自我们手机浏览器上一段的请求消息,它包含了请求行、请求头、空行和报文主体
其中最重要的信息是第一行的:
1 | GET / HTTP/1.1 |
这一行包含了3个信息,第一个GET
表示浏览器使用GET方式发出请求,第二个/
表示浏览器想访问网站的根文件夹,第三个HTTP/1.1
表示浏览器使用的是 HTTP 1.1 协议。
首先是请求方法GET
,HTTP协议中定义了各种请求方法,其中GET
表示浏览器想要获取当前页面信息,于是示例中通过conn:send("<h1> Hello, NodeMcu.</h1>")
返回了页面信息,浏览器收到这段信息就会显示出来。不过其实这个没什么关系,毕竟是协议,也就是说这不是强制性的,你完全可以按照你的方式来写服务器,用自己的方式处理各种请求。
然后是URL/
,我们可以这样理解,一个网站就是电脑里的一个文件夹,URL就是我们电脑文件夹的路径,/
就代表这个文件夹的根目录,就是指这个文件夹本身,假设这个文件夹里有一个文件叫index.html
,那么我们就可以用/index.html
来表示。不过这个在示例中并没有太大作用,我们之后再详细解释。
最后是协议版本HTTP/1.1
,其实我们写HTTP服务器的本质就是处理浏览器发送过来的请求。10年前我们还在用XP,现在我们已经用上了win10,谁敢保证我们10年后我们处理请求的方式跟现在一样呢?所以我们就用这个协议版本加以区分,表示服务器应该按 HTTP 1.1 的方式来处理请求。
HTTP响应
浏览器发送过来一段请求,我们处理完之后理所当然的需要返回一个响应消息告诉浏览器我们已经处理完了这段请求。
在官网示例中conn:send("<h1> Hello, NodeMcu.</h1>")
就完成了这个操作,但这并不完整,一个完整的响应应该包含状态行、响应头、空行和报文主体。
我们修改一下示例代码
1 | srv = net.createServer(net.TCP) |
浏览器正常是不会在页面中显示状态行和响应头的,所以我们要使用浏览器的开发者工具查看。
这里有个问题,就是刚刚说了,好像很多人的电脑(尤其windows系统)都连不上nodemcu的热点,所以当我们无法接连nodemcu热点时,可以使用STA+AP模式,先让nodemcu和电脑连接到同一个热点,然后用电脑访问nodemcu在STA模式下的ip地址
然后我们就可以用浏览器的开发者工具查看完整的响应消息了
解析HTTP请求
现在我们大致明白HTTP协议是怎么运作的了,但是我们究竟要怎么通过HTTP控制nodemcu呢?这个时候就要把HTTP请求中包含的信息解析出来,然后让nodemcu执行对应的操作。
在这里,我们可以通过解析请求中的URL来判断nodemcu应该执行什么操作。
1 | -- 解析请求行 |
关于lua的正则可以查看Lua 5.3参考手册的6.4.1章匹配模式
例如当我们访问的url为http://192.168.0.103/config?led=on
,将会得到如下req
1 | req = { |
通过判断req.qurey中的参数,我们就可以让nodemcu执行我们想要的操作。
以上就是一个简单的HTTP服务器。
通过网页控制LED开关
有了刚才的函数,我们只需要解析URL中的参数就能控制LED灯了。
1 | -- 使用pin4的指示灯 |
完美。
开头的链接中提供了一个别人写好的HTTP框架,不嫌看源码麻烦的话可以试试(总比自己写方便)。
至于关于怎么写网页可以看这个HTML 教程