-
最近在使用ESP32搭建web服务器测试,发现esp32搭建这类开发环境还是比较方便的。具体的http协议这里就不再赘述,我们主要说一下如何使用ESP32提供的API来搭建我们的http web。 一、web服务器搭建过程 1、配置web服务器 在ESP-IDF中,Web服务器使用httpd组件实现。我们需要先创建httpd_config_t结构体,指定服务器的端口、最大并发连接数、URI匹配处理器等选项。然后,我们通过调用httpd_start函数来启动Web服务器。(使用默认的配置就可以,包括端口号都已经默认配置好了) httpd_config_t config = HTTPD_DEFAULT_CONFIG(); httpd_handle_t server = NULL; // 设置服务器端口为80 config.server_port = 80; // 创建HTTP服务器句柄 if (httpd_start(&server, &config) != ESP_OK) { printf("Error starting server!\n"); return; } 2、 注册 URI处理器 在Web服务器启动后,我们需要为不同的URI注册处理器函数。当Web服务器接收到请求时,会根据请求的URI选择相应的处理器函数进行处理。在ESP-IDF中,我们可以使用httpd_register_uri_handler函数注册URI处理器。该函数的原型如下 esp_err_t httpd_register_uri_handler(httpd_handle_t hd, const httpd_uri_t *uri) 其中,hd参数为HTTP服务器句柄;uri参数为包含URI路径、HTTP方法、处理函数等信息的结构体指针。例如: static const httpd_uri_t echo = { .uri = "/", .method = HTTP_POST, .handler = echo_post_handler, .user_ctx = NULL }; static esp_err_t echo_post_handler(httpd_req_t *req) { char buf[100]; // char ssid[10]; // char pswd[10]; int ret, remaining = req->content_len; while (remaining > 0) { /* Read the data for the request */ if ((ret = httpd_req_recv(req, buf, MIN(remaining, sizeof(buf)))) <= 0) { if (ret == HTTPD_SOCK_ERR_TIMEOUT) { /* Retry receiving if timeout occurred */ continue; } return ESP_FAIL; } /* Send back the same data */ httpd_resp_send_chunk(req, buf, ret); remaining -= ret; esp_err_t e = httpd_query_key_value(buf,"ssid",wifi_name,sizeof(wifi_name)); if(e == ESP_OK) { printf("ssid = %s\r\n",wifi_name); } else { printf("error = %d\r\n",e); } e = httpd_query_key_value(buf,"password",wifi_password,sizeof(wifi_password)); if(e == ESP_OK) { printf("pswd = %s\r\n",wifi_password); } else { printf("error = %d\r\n",e); } /* Log data received */ ESP_LOGI(TAG, "=========== RECEIVED DATA =========="); ESP_LOGI(TAG, "%.*s", ret, buf); ESP_LOGI(TAG, "===================================="); } // End response httpd_resp_send_chunk(req, NULL, 0); if(strcmp(wifi_name ,"\0")!=0 && strcmp(wifi_password,"\0")!=0) { xSemaphoreGive(ap_sem); ESP_LOGI(TAG, "set wifi name and password successfully! goto station mode"); } return ESP_OK; } html的网页如下:这个网页包含了按钮的定义,以及发送json格式的数据。 最后送json数据的时候,要用JSON.stringify方法格式化data,否则esp32解析json会报错,此处一定要注意!!! 整体html界面非常简单,没有基础的也很容易读懂,里面写了一个js函数,该函数是在点击按钮的时候触发,功能主要是读取文本框输入的数据,将数据封装为json格式,然后post发送数据,xhttp.open(“POST”, “/wifi_data”, true);中的url “/wifi_data”和esp32服务端中的定义要一致,否则是无法成功的。 <!DOCTYPE html> <head> <meta charset="utf-8"> <title>Web server system</title> </head> <table class="fixed" border="5"> <col width="1000px" /><col width="500px" /> <tr><td> <h2 style=" text-align:center;"> **** Web Server ***</h2> <h3>wifi 密码配置</h3> <div> <label for="name">wifi名称</label> <input type="text" id="wifi" name="car_name" placeholder="ssid"> <br> <label for="type">密码</label> <input type="text" id="code" name="car_type" placeholder="password"> <br> <button id ="send_WIFI" type="button" onclick="send_wifi()">提交</button> </div> </td><td> <table border="10"> <tr> <td> <label for="newfile">Upload a file</label> </td> <td colspan="2"> <input id="newfile" type="file" onchange="setpath()" style="width:100%;"> </td> </tr> <tr> <td> <label for="filepath">Set path on server</label> </td> <td> <input id="filepath" type="text" style="width:100%;"> </td> <td> <button id="upload" type="button" onclick="upload()">Upload</button> </td> </tr> </table> </td></tr> </table> <script> function setpath() { var default_path = document.getElementById("newfile").files[0].name; document.getElementById("filepath").value = default_path; } function upload() { var filePath = document.getElementById("filepath").value; var upload_path = "/upload/" + filePath; var fileInput = document.getElementById("newfile").files; /* Max size of an individual file. Make sure this * value is same as that set in file_server.c */ var MAX_FILE_SIZE = 200*1024; var MAX_FILE_SIZE_STR = "200KB"; if (fileInput.length == 0) { alert("No file selected!"); } else if (filePath.length == 0) { alert("File path on server is not set!"); } else if (filePath.indexOf(' ') >= 0) { alert("File path on server cannot have spaces!"); } else if (filePath[filePath.length-1] == '/') { alert("File name not specified after path!"); } else if (fileInput[0].size > 200*1024) { alert("File size must be less than 200KB!"); } else { document.getElementById("newfile").disabled = true; document.getElementById("filepath").disabled = true; document.getElementById("upload").disabled = true; var file = fileInput[0]; var xhttp = new XMLHttpRequest(); xhttp.onreadystatechange = function() { if (xhttp.readyState == 4) { if (xhttp.status == 200) { document.open(); document.write(xhttp.responseText); document.close(); } else if (xhttp.status == 0) { alert("Server closed the connection abruptly!"); location.reload() } else { alert(xhttp.status + " Error!\n" + xhttp.responseText); location.reload() } } }; xhttp.open("POST", upload_path, true); xhttp.send(file); } } function send_wifi() { var input_ssid = document.getElementById("wifi").value; var input_code = document.getElementById("code").value; var xhttp = new XMLHttpRequest(); xhttp.open("POST", "/wifi_data", true); xhttp.onreadystatechange = function() { if (xhttp.readyState == 4) { if (xhttp.status == 200) { console.log(xhttp.responseText); } else if (xhttp.status == 0) { alert("Server closed the connection abruptly!"); location.reload() } else { alert(xhttp.status + " Error!\n" + xhttp.responseText); location.reload() } } }; var data = { "wifi_name":input_ssid, "wifi_code":input_code } xhttp.send(JSON.stringify(data)); } </script> static esp_err_t html_default_get_handler(httpd_req_t *req) { // /* Send HTML file header */ // httpd_resp_sendstr_chunk(req, "<!DOCTYPE html><html><body>"); /* Get handle to embedded file upload script */ extern const unsigned char upload_script_start[] asm("_binary_upload_script_html_start"); extern const unsigned char upload_script_end[] asm("_binary_upload_script_html_end"); const size_t upload_script_size = (upload_script_end - upload_script_start); /* Add file upload form and script which on execution sends a POST request to /upload */ httpd_resp_send_chunk(req, (const char *)upload_script_start, upload_script_size); /* Send remaining chunk of HTML file to complete it */ httpd_resp_sendstr_chunk(req, "</body></html>
-
FunctionGraph集成express,找不到fgs-express模块,看文档说是内置的模块
-
尊敬的华为云客户::华为云计划于2019/7/22 00:00(北京时间)将数据仓库服务-Express加速查询功能转商。正式商用后,Express加速查询功能将于2019/07/22 00:00(北京时间)开始收费。数据仓库服务-Express价格30元/TB,按需计费,根据Express实际扫描的字节数收费所有DWS集群默认使用该功能,为了保障您的权益,在此建议您在服务正式商用后(2019/07/22 00:00),如果您需要继续Express查询加速功能,请前往服务产品页了解具体计费说明;如果您不再需要使用,请停止进行OBS外表查询,并与我们联系帮助您屏蔽Express功能,避免产生不必要的费用。更多关于数据仓库服务-Express的产品介绍,请您点击了解。如您有任何问题,可随时通过工单或者服务热线(950808)与我们联系。感谢您对华为云的支持!
推荐直播
-
在昇腾云上部署使用DeepSeek
2025/02/14 周五 16:30-18:00
Hao-资深昇腾云解决方案专家
昇腾云上有多种方法部署DeepSeek,讲师一步步演示,解析配置参数的含义和推荐的选择。学完一起动手搭建自己的DeepSeek环境吧!
回顾中
热门标签