目的
Arduino for ESP8266 和 Arduino for ESP32 中默认就有WebServer,不过这些WebServer都是同步的,不支持同时处理多个连接,这在很多时候其实是不太好用的。
如果用户请求一个页面,该页面中链接了很多文件的情况下,因为不支持同时处理多个连接,其中部分文件可能就获取失败了,最终导致呈现在用户眼前的页面功能缺失。再或者有多个用户频繁的发起请求,其中部分请求也有可能会无法响应。
使用ESPAsyncWebServer就可以极大的规避上述问题,使在Arduino for ESP8266&ESP32中搭建WebServer真正可用、好用。
ESPAsyncWebServer项目地址如下:
https://github.com/me-no-dev/ESPAsyncWebServer
本文中各例程演示均在ESP32中进行。
特征
- 使用异步方式意味着可以同时处理多个连接;
- 支持WebSocket和EventSource;
- 支持URL Rewrite;
- 支持ServeStatic,可实现Cache-Control、Last-Modified、default index等功能;
- 带有简单的模板引擎;
安装
ESPAsyncWebServer项目官方是推荐使用PlatformIO作为开发工具来使用,相关的安装使用方法可以查看官方文档。本文中将以传统Arduino IDE作为使用说明。首先下载相关的库:
另外ESPAsyncWebServer库是基于异步TCP库之上的,这个也需要另外下载:
ESP8266使用ESPAsyncTCP库 - https://github.com/me-no-dev/ESPAsyncTCP
ESP32使用AsyncTCP库 - https://github.com/me-no-dev/AsyncTCP
下载相关库的zip包后在Arduino IDE中选择: 项目 > 加载库 > 添加 .ZIP 库
,库添加完成后就可以使用了。
如果你想将库文件都包含在自己的项目中那可以将相关文件和文件加放到项目文件夹里,然后修改头文件中的相关引用,将 #include <...>
修改为 #include "..."
,涉及的文件有好几个,如果没有用上面的方式添加过库的可以通过编译时报错的信息来查找哪些地方需要修改。
快速体验
ESPAsyncWebServer功能很强大,但最基本的使用非常简单,在安装完库之后只要以下几步即可使用:
- 引入相应库
#include <ESPAsyncWebServer.h>
; - 声明
AsyncWebServer
对象并设置端口号,一般WebServer端口号使用80
; - 使用
on()
方法注册链接与回调函数; - 使用
begin()
方法启动服务器进行请求监听;
下面是个最基础的使用例程:
#include <WiFi.h>
#include <ESPAsyncWebServer.h> //引入相应库
const char *ssid = "********";
const char *password = "********";
AsyncWebServer server(80); //声明WebServer对象
void handleRoot(AsyncWebServerRequest *request) //回调函数
{
Serial.println("User requested.");
request->send(200, "text/plain", "Hello World!"); //向客户端发送响应和内容
}
void setup()
{
Serial.begin(115200);
Serial.println();
WiFi.mode(WIFI_STA);
WiFi.setSleep(false);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED)
{
delay(500);
Serial.print(".");
}
Serial.println("Connected");
Serial.print("IP Address:");
Serial.println(WiFi.localIP());
server.on("/", HTTP_GET, handleRoot); //注册链接"/"与对应回调函数
server.begin(); //启动服务器
Serial.println("Web server started");
}
void loop(){}
上面的演示中除去连接WiFi的代码,真正ESPAsyncWebServer部分代码没多少,使用起来非常简单,大部分时候我们需要关心的就是 on() 方法和与它绑定的回调函数。
on() 方法中第二个参数可选值为 HTTP_GET
、 HTTP_POST
、 HTTP_DELETE
、 HTTP_PUT
、 HTTP_PATCH
、 HTTP_HEAD
、 HTTP_OPTIONS
、 HTTP_ANY
这些HTTP方法。
除了 on() 方法外还有个 onNotFound()
方法,用户访问未注册的链接时就会执行该方法绑定的回调函数。
上面的回调函数中用了 request->send()
方式向客户端发送了消息,上面例子中参数分别填入了HTTP状态码、文件类型、响应数据。 send() 方法还有很多重载形式,会另外写文章进行介绍。
下面是个稍丰富点的例程:
#include <WiFi.h>
#include <ESPAsyncWebServer.h> //引入相应库
const char *ssid = "********";
const char *password = "********";
AsyncWebServer server(80); //声明WebServer对象
void handleRoot(AsyncWebServerRequest *request) //回调函数
{
Serial.println("User requested /");
request->send(200, "text/plain", "Hello World!"); //向客户端发送响应和内容
}
void notFound(AsyncWebServerRequest *request) //回调函数
{
Serial.println("User requested unknow");
request->send(404, "text/plain", "Not found"); //向客户端发送响应和内容
}
void setup()
{
Serial.begin(115200);
Serial.println();
WiFi.mode(WIFI_STA);
WiFi.setSleep(false);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED)
{
delay(500);
Serial.print(".");
}
Serial.println("Connected");
Serial.print("IP Address:");
Serial.println(WiFi.localIP());
server.on("/", HTTP_GET, handleRoot); //注册链接"/"与对应回调函数
server.on("/lambda", HTTP_GET, [](AsyncWebServerRequest *request) { //注册链接"/lambda"与对应回调函数(匿名函数形式声明)
Serial.println("User requested /lambda");
request->send(200, "text/plain", "lambda callback page"); //向客户端发送响应和内容
});
server.onNotFound(notFound); //用户访问未注册的链接时执行notFound()函数
server.begin(); //启动服务器
Serial.println("Web server started");
}
void loop() {}
注意事项
- 该库对于用户请求的解析并不是在loop()中进行的;
- 基于上面的原因不能在请求的回调函数中使用 yield 和 delay 这类函数;
- 单个请求只能发送单个响应;
总结
ESPAsyncWebServer入门使用是非常简单的,但实际上ESPAsyncWebServer功能非常多,更多内容可以查看项目官方的文档和例程,或者我的其他ESPAsyncWebServer的文章:
《Arduino for ESP8266&ESP32适用库ESPAsyncWebServer:快速入门》
《Arduino for ESP8266&ESP32适用库ESPAsyncWebServer:事件处理绑定》
《Arduino for ESP8266&ESP32适用库ESPAsyncWebServer:请求与响应》
《Arduino for ESP8266&ESP32适用库ESPAsyncWebServer:静态文件和模板引擎》
《Arduino for ESP8266&ESP32适用库ESPAsyncWebServer:WebSocket和EventSource》