当前位置:   article > 正文

ESPAsyncWebServer 库

espasyncwebserver

https://github.com/me-no-dev/ESPAsyncWebServer   里面有参考实例和源文件

该库还支持WebSocket、EventSource

头文件:

  1. #include <Arduino.h>
  2. #ifdef ESP32
  3. #include <WiFi.h>
  4. #include <AsyncTCP.h>
  5. #elif defined(ESP8266)
  6. #include <ESP8266WiFi.h>
  7. #include <ESPAsyncTCP.h>
  8. #endif
  9. #include <ESPAsyncWebSrv.h>

一、HTTP请求 (代码片段):

  1. #include <ESPAsyncWebServer.h> //引入相应库
  2. AsyncWebServer server(80); //声明WebServer对象
  3. void handleRoot(AsyncWebServerRequest *request) //回调函数
  4. {
  5. Serial.println("User requested.");
  6. request->send(200, "html", "<div>Hello World!</div>"); //向客户端发送响应和内容
  7. }
  8. void setup()
  9. {
  10. server.on("/", HTTP_GET, handleRoot); //注册链接"/"与对应回调函数
  11. server.on("/change", HTTP_GET, [] (AsyncWebServerRequest *request) {
  12. String name;
  13. if (request->hasParam("name")) {
  14. name = request->getParam("name")->value();
  15. val = atof(String(request->getParam("val")->value()).c_str());
  16. if(name == "Z"){
  17. Z = val;
  18. int pwmVal = map((int)val,0,100,1023,0); // 用户请求数值为0-100,转为0-1023
  19. ledcWrite(0, pwmVal);//指定通道输出一定占空比波形
  20. }else if(name == "A"){
  21. A = val;
  22. }else if(name == "B"){
  23. B = val;
  24. }
  25. } else {
  26. name = "No message sent";
  27. }
  28. request->send(200, "text/plain", "Hello, GET: " + name);
  29. });
  30. server.begin(); //启动服务器
  31. }
  32. void loop(){}

1、方法说明:

ESPAsyncWebServer中对于请求的调取实在回调函数中进行的,回调函数传入一个 AsyncWebServerRequest 对象

  1. request->version(); // uint8_t: 0 = HTTP/1.0, 1 = HTTP/1.1
  2. request->method(); // enum: HTTP_GET, HTTP_POST, HTTP_DELETE, HTTP_PUT, HTTP_PATCH, HTTP_HEAD, HTTP_OPTIONS
  3. // HTTP_GET = 0b00000001, HTTP_POST = 0b00000010, HTTP_DELETE = 0b00000100, HTTP_PU = 0b00001000, HTTP_PATCH = 0b00010000, HTTP_HEAD = 0b00100000, HTTP_OPTIONS = 0b01000000, HTTP_ANY = 0b01111111
  4. request->url(); // String: URL of the request (not including host, port or GET parameters)
  5. request->host(); // String: The requested host (can be used for virtual hosting)
  6. request->contentType(); // String: ContentType of the request (not avaiable in Handler::canHandle)
  7. request->contentLength(); // size_t: ContentLength of the request (not avaiable in Handler::canHandle)
  8. request->multipart(); // bool: True if the request has content type "multipart"
  9. request->headers(); // int 返回头参数长度
  10. request->params(); // int 返回get post 参数长度

2、处理请求头:

  1. int headers = request->headers();
  2. // 遍历请求头
  3. int i;
  4. for(i=0;i<headers;i++){
  5. AsyncWebHeader* h = request->getHeader(i);
  6. Serial.printf("HEADER[%s]: %s\n", h->name().c_str(), h->value().c_str());
  7. // 下面行功能同上面两行
  8. //Serial.printf("HEADER[%s]: %s\n", request->headerName(i).c_str(), request->header(i).c_str());
  9. }
  10. /******************************************************************************/
  11. // 指定参数名称
  12. if(request->hasHeader("MyHeader")){ // 获取请求头参数
  13. AsyncWebHeader* h = request->getHeader("MyHeader");
  14. Serial.printf("MyHeader: %s\n", h->value().c_str());
  15. // 下面行功能同上面两行
  16. // Serial.printf("MyHeader: %s\n", request->header("MyHeader").c_str());
  17. }

 3、处理get post 参数:

(post请求时,用getParam('name')指定参数名,得不到post参数,需要用下面的方法遍历,用不知道为什么。有明白的麻烦留个言,谢谢!)

  1. int params = request->params();
  2. for(int i=0;i<params;i++){
  3. AsyncWebParameter* p = request->getParam(i);
  4. if(p->isFile()){ //p->isPost() is also true
  5. Serial.printf("FILE[%s]: %s, size: %u\n", p->name().c_str(), p->value().c_str(), p->size());
  6. } else if(p->isPost()){
  7. Serial.printf("POST[%s]: %s\n", p->name().c_str(), p->value().c_str());
  8. } else { //GET
  9. Serial.printf("GET[%s]: %s\n", p->name().c_str(), p->value().c_str());
  10. }
  11. }
  12. // 下面语句功能同上面
  13. //int args = request->args();
  14. //for(int i=0;i<args;i++){
  15. // Serial.printf("ARG[%s]: %s\n", request->argName(i).c_str(), request->arg(i).c_str());
  16. //}
  17. /*********************************************************************************/
  18. // 指定参数
  19. if(request->hasParam("download")) //Check if GET parameter exists
  20. AsyncWebParameter* p = request->getParam("download");
  21. if(request->hasParam("download", true)) //Check if POST (but not File) parameter exists
  22. AsyncWebParameter* p = request->getParam("download", true);
  23. if(request->hasParam("download", true, true)) //Check if FILE was uploaded
  24. AsyncWebParameter* p = request->getParam("download", true, true);
  25. // 下面语句功能同上面
  26. //if(request->hasArg("download"))
  27. // String arg = request->arg("download");

4、发送响应:

  1. request->send(200, "text/plain", "Hello World!");
  2. // 发送 PROGMEM 字符串
  3. const char index_html[] PROGMEM = "..."; // large char array, tested with 14k
  4. request->send_P(200, "text/html", index_html);

二、websocket使用 (代码片段): 

  1. #include <ESPAsyncWebServer.h> //引入相应库
  2. AsyncWebServer server(80); //声明WebServer对象
  3. AsyncWebSocket ws("/"); // WebSocket对象,url为/
  4. void handleRoot(AsyncWebServerRequest *request) //回调函数
  5. {
  6. Serial.println("User requested.");
  7. request->send(200, "html", "<p>Hello World!</p>"); //向客户端发送响应和内容
  8. }
  9. // WebSocket事件回调函数
  10. void onEventHandle(AsyncWebSocket *server, AsyncWebSocketClient *client, AwsEventType type, void *arg, uint8_t *data, size_t len)
  11. {
  12. if (type == WS_EVT_CONNECT) // 有客户端建立连接
  13. {
  14. Serial.printf("ws[%s][%u] connect\n", server->url(), client->id());
  15. client->printf("Hello Client %u !", client->id()); // 向客户端发送数据
  16. client->ping(); // 向客户端发送ping
  17. }
  18. else if (type == WS_EVT_DISCONNECT) // 有客户端断开连接
  19. {
  20. Serial.printf("ws[%s][%u] disconnect: %u\n", server->url(), client->id());
  21. }
  22. else if (type == WS_EVT_ERROR) // 发生错误
  23. {
  24. Serial.printf("ws[%s][%u] error(%u): %s\n", server->url(), client->id(), *((uint16_t *)arg), (char *)data);
  25. }
  26. else if (type == WS_EVT_PONG) // 收到客户端对服务器发出的ping进行应答(pong消息)
  27. {
  28. Serial.printf("ws[%s][%u] pong[%u]: %s\n", server->url(), client->id(), len, (len) ? (char *)data : "");
  29. }
  30. else if (type == WS_EVT_DATA) // 收到来自客户端的数据
  31. {
  32. AwsFrameInfo *info = (AwsFrameInfo *)arg;
  33. Serial.printf("ws[%s][%u] frame[%u] %s[%llu - %llu]: ", server->url(), client->id(), info->num, (info->message_opcode == WS_TEXT) ? "text" : "binary", info->index, info->index + len);
  34. data[len] = 0;
  35. Serial.printf("%s\n", (char *)data);
  36. }
  37. }
  38. void setup()
  39. {
  40. ws.onEvent(onEventHandle); // 绑定回调函数
  41. server.addHandler(&ws); // 将WebSocket添加到服务器中
  42. server.on("/", HTTP_GET, handleRoot); //注册链接"/"与对应回调函数
  43. server.on("/led", HTTP_GET, [](AsyncWebServerRequest *request) { //注册链接"/led"与对应回调函数(匿名函数形式声明)
  44. request->send(200, "text/plain", "hello"); //向客户端发送响应和内容
  45. });
  46. server.begin(); //启动服务器
  47. delay(1000);
  48. ws.textAll("{\"r\":" + String(str_r) + ",\"T\":" + String(str_T) + "}"); // 向所有建立连接的客户端发送数据
  49. }
  50. void loop(){
  51. ws.cleanupClients(); // 关闭过多的WebSocket连接以节省资源
  52. }

1、通过AsyncWebSocketClient对象发送文本消息:

        void text(const char * message, size_t len);
        void text(const char * message);
        void text(uint8_t * message, size_t len);
        void text(char * message);
        void text(const String &message);
        void text(const __FlashStringHelper *data);
        void text(AsyncWebSocketMessageBuffer *buffer);

 2、通过AsyncWebSocket对象发送:

   void text(uint32_t id, const char * message, size_t len);

 一般发送json数据:

  1. char destBuf[80] = { 0 }; // 初始化为 0 字符
  2. sprintf(destBuf, "{\"time\": \"20%02d-%02d-%02d 星期%d %02d:%02d:%02d\",\"wifi_st\":%d,\"ssid\":\"%s\",\"counter\":%d}",userData.Y,userData.M,userData.D,userData.w,userData.h ,userData.m,userData.s,WiFi.status(),WiFi.SSID(),pulseCount); // .1f 表示仅输出小数点后 1 位
  3. ws.textAll(destBuf);

3、具体的更多方法,查看库源文件,更详细 -_-!

附 html js部分:

  1. <html lang='en'>
  2. <head><meta charset='UTF-8'><meta name='viewport' content='width=device-width, initial-scale=1.0'><title>控制台</title></head>
  3. <body>
  4. <form action='/change' method='POST'>
  5. <div><label>当前转速(r) </label><input id='r' class="v" type="text" name="r" value="47" readonly> r/s <label>&nbsp;&nbsp;|&nbsp;&nbsp;LED周期(T) </label><input class="v" type="text" name="T" id='T' value="20.5" readonly> ms</div>
  6. <br>
  7. <!-- <div><label>调节电机转速: </label><button style= "width: 30px;" id='down' type = 'button' onclick="d()">-</button><button style= "width: 30px;" id='' type = 'button' onclick="u()">+</button></div> -->
  8. <div><label>调节电机转速: </label>
  9. <input style="width:60%;" name = "Z" type="range" min="0" max="100" value="100" oninput="rangeValue.innerText = this.value" onchange="s('Z',this.value)"><span id="rangeValue"></span>
  10. </div>
  11. <div><label>LED固定转角(A) </label><input class="v" type="text" name="A" value="15" onblur="s('A',this.value)"></div>
  12. <div><label>LED超前角度(B) </label><input class="v" type="text" name="B" value="2" onblur="s('B',this.value)"></div>
  13. <br>
  14. <label>备注: T= (1+ 1/r x (B/360)) / (rx(360/A)) :一个分解动作的时间 除以 分度</label>
  15. <br><br>
  16. </form>
  17. <div onclick="sd()">点击向服务器发送数据</div><div id="info"></div>
  18. </body>
  19. <script>
  20. var ws;
  21. var json;
  22. window.onload = function () {
  23. if ("WebSocket" in window) {
  24. ws = new WebSocket("ws://" + window.location.host + "/");
  25. ws.onopen = function () {
  26. document.getElementById("info").innerHTML += "WebSocket连接成功!" + "<br>";
  27. ws.send("connect ok!");
  28. };
  29. ws.onmessage = function (evt) {
  30. console.log(evt.data);
  31. try{
  32. json = JSON.parse(evt.data);
  33. console.log("is JSON");
  34. if(typeof(json.time) != "undefined"){
  35. document.getElementById('time').innerHTML = json.time;
  36. }
  37. if(typeof(json.alert) != "undefined"){
  38. alert(json.alert);
  39. }
  40. }catch{
  41. document.getElementById("info").innerHTML += evt.data + "<br>";
  42. }
  43. };
  44. ws.onerror = function () {
  45. document.getElementById("info").innerHTML += "通讯发送错误!" + "<br>";
  46. };
  47. ws.onclose = function () {
  48. document.getElementById("info").innerHTML += "WebSocketTest连接已关闭!" + "<br>";
  49. };
  50. } else {
  51. document.getElementById("info").innerHTML = "浏览器不支持 WebSocket!";
  52. }
  53. };
  54. function sd() {
  55. console.log('send "hahaha~~~"');
  56. ws.send("hahaha~~~");
  57. }
  58. var val;
  59. var vname;
  60. function s(vname,val){
  61. console.log(vname,val);
  62. var xhr=new XMLHttpRequest();
  63. xhr.open("GET","/change?name=" + vname + "&val=" + val,true);
  64. xhr.send();
  65. xhr.onreadystatechange=function(){
  66. if(xhr.readyState==4 && xhr.status==200){
  67. console.log(xhr.response);
  68. }
  69. }
  70. }
  71. </script>
  72. </html>

笔记引用自:

《Arduino for ESP8266&ESP32适用库ESPAsyncWebServer:快速入门》

《Arduino for ESP8266&ESP32适用库ESPAsyncWebServer:请求与响应》

《Arduino for ESP8266&ESP32适用库ESPAsyncWebServer:WebSocket和EventSource》

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家自动化/article/detail/196266
推荐阅读
相关标签
  

闽ICP备14008679号