zoukankan      html  css  js  c++  java
  • ESP32-http server笔记

    基于ESP-IDF4.1

    #include <esp_wifi.h>
    #include <esp_event.h>
    #include <esp_log.h>
    #include <esp_system.h>
    #include <nvs_flash.h>
    #include <sys/param.h>
    #include "nvs_flash.h"
    #include "esp_netif.h"
    #include "esp_eth.h"
    #include "protocol_examples_common.h"
    
    #include <esp_http_server.h>
    
    /* 
     * 演示服务端创建get和post处理服务
     */
    
    static const char *TAG = "example";
    
    /* HTTP GET 处理程序 */
    static esp_err_t hello_get_handler(httpd_req_t *req)
    {
        char*  buf;
        size_t buf_len;
    
        //获取消息头值得长度并且分配内存,而外1个字节存储null终止符
        buf_len = httpd_req_get_hdr_value_len(req, "Host") + 1;
        if (buf_len > 1) {
            buf = malloc(buf_len);
            /* 将null结尾的字符串值复制到缓冲区 */
            if (httpd_req_get_hdr_value_str(req, "Host", buf, buf_len) == ESP_OK) {
                ESP_LOGI(TAG, "Found header => Host: %s", buf);
            }
            free(buf);
        }
    
        buf_len = httpd_req_get_hdr_value_len(req, "Test-Header-2") + 1;
        if (buf_len > 1) {
            buf = malloc(buf_len);
            if (httpd_req_get_hdr_value_str(req, "Test-Header-2", buf, buf_len) == ESP_OK) {
                ESP_LOGI(TAG, "Found header => Test-Header-2: %s", buf);
            }
            free(buf);
        }
    
        buf_len = httpd_req_get_hdr_value_len(req, "Test-Header-1") + 1;
        if (buf_len > 1) {
            buf = malloc(buf_len);
            if (httpd_req_get_hdr_value_str(req, "Test-Header-1", buf, buf_len) == ESP_OK) {
                ESP_LOGI(TAG, "Found header => Test-Header-1: %s", buf);
            }
            free(buf);
        }
    
        // 读取URL查询字符串长度并分配内存空间
        buf_len = httpd_req_get_url_query_len(req) + 1;
        if (buf_len > 1) {
            buf = malloc(buf_len);
            if (httpd_req_get_url_query_str(req, buf, buf_len) == ESP_OK) {
                ESP_LOGI(TAG, "Found URL query => %s", buf);
                char param[32];
                // 从查询字符串获取键值
                if (httpd_query_key_value(buf, "query1", param, sizeof(param)) == ESP_OK) {
                    ESP_LOGI(TAG, "Found URL query parameter => query1=%s", param);
                }
                if (httpd_query_key_value(buf, "query3", param, sizeof(param)) == ESP_OK) {
                    ESP_LOGI(TAG, "Found URL query parameter => query3=%s", param);
                }
                if (httpd_query_key_value(buf, "query2", param, sizeof(param)) == ESP_OK) {
                    ESP_LOGI(TAG, "Found URL query parameter => query2=%s", param);
                }
            }
            free(buf);
        }
    
        /* 设置自定义消息头 */
        httpd_resp_set_hdr(req, "Custom-Header-1", "Custom-Value-1");
        httpd_resp_set_hdr(req, "Custom-Header-2", "Custom-Value-2");
    
        //用户上下文通过字符串响应自定义消息头和消息体
        const char* resp_str = (const char*) req->user_ctx;
        httpd_resp_send(req, resp_str, strlen(resp_str));
    
        //检查http请求消息头是否可以被读取
        if (httpd_req_get_hdr_value_len(req, "Host") == 0) {
            ESP_LOGI(TAG, "Request headers lost");
        }
        return ESP_OK;
    }
    
    static const httpd_uri_t hello = {
        .uri       = "/hello",
        .method    = HTTP_GET,
        .handler   = hello_get_handler,
        .user_ctx  = "Hello World!"
    };
    
    /* HTTP POST处理 */
    static esp_err_t echo_post_handler(httpd_req_t *req)
    {
        char buf[100];
        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;
    
            /* 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);
        return ESP_OK;
    }
    
    static const httpd_uri_t echo = {
        .uri       = "/echo",
        .method    = HTTP_POST,
        .handler   = echo_post_handler,
        .user_ctx  = NULL
    };
    
    /* 
     * 自定义错误处理
     */
    esp_err_t http_404_error_handler(httpd_req_t *req, httpd_err_code_t err)
    {
        if (strcmp("/hello", req->uri) == 0) {
            httpd_resp_send_err(req, HTTPD_404_NOT_FOUND, "/hello URI is not available");
            /* Return ESP_OK to keep underlying socket open */
            return ESP_OK;
        } else if (strcmp("/echo", req->uri) == 0) {
            httpd_resp_send_err(req, HTTPD_404_NOT_FOUND, "/echo URI is not available");
            /* Return ESP_FAIL to close underlying socket */
            return ESP_FAIL;
        }
        /* For any other URI send 404 and close socket */
        httpd_resp_send_err(req, HTTPD_404_NOT_FOUND, "Some 404 error message");
        return ESP_FAIL;
    }
    
    /* 
     * HTTP POST处理程序
     */
    static esp_err_t ctrl_put_handler(httpd_req_t *req)
    {
        char buf;
        int ret;
    
        if ((ret = httpd_req_recv(req, &buf, 1)) <= 0) {
            if (ret == HTTPD_SOCK_ERR_TIMEOUT) {
                httpd_resp_send_408(req);
            }
            return ESP_FAIL;
        }
    
        if (buf == '0') {
            /* URI handlers can be unregistered using the uri string */
            ESP_LOGI(TAG, "Unregistering /hello and /echo URIs");
            httpd_unregister_uri(req->handle, "/hello");
            httpd_unregister_uri(req->handle, "/echo");
            /* Register the custom error handler */
            httpd_register_err_handler(req->handle, HTTPD_404_NOT_FOUND, http_404_error_handler);
        }
        else {
            ESP_LOGI(TAG, "Registering /hello and /echo URIs");
            httpd_register_uri_handler(req->handle, &hello);
            httpd_register_uri_handler(req->handle, &echo);
            /* Unregister custom error handler */
            httpd_register_err_handler(req->handle, HTTPD_404_NOT_FOUND, NULL);
        }
    
        /* Respond with empty body */
        httpd_resp_send(req, NULL, 0);
        return ESP_OK;
    }
    
    static const httpd_uri_t ctrl = {
        .uri       = "/ctrl",
        .method    = HTTP_PUT,
        .handler   = ctrl_put_handler,
        .user_ctx  = NULL
    };
    
    //启动web服务
    static httpd_handle_t start_webserver(void)
    {
        httpd_handle_t server = NULL;
        httpd_config_t config = HTTPD_DEFAULT_CONFIG();
    
        // 启动httpd服务
        ESP_LOGI(TAG, "Starting server on port: '%d'", config.server_port);
        if (httpd_start(&server, &config) == ESP_OK) {
            // 设置URI处理程序
            ESP_LOGI(TAG, "Registering URI handlers");
            httpd_register_uri_handler(server, &hello);
            httpd_register_uri_handler(server, &echo);
            httpd_register_uri_handler(server, &ctrl);
            return server;
        }
    
        ESP_LOGI(TAG, "Error starting server!");
        return NULL;
    }
    
    //停止web服务
    static void stop_webserver(httpd_handle_t server)
    {
        // 停止httpd服务
        httpd_stop(server);
    }
    
    //断网处理程序
    static void disconnect_handler(void* arg, esp_event_base_t event_base, 
                                   int32_t event_id, void* event_data)
    {
        httpd_handle_t* server = (httpd_handle_t*) arg;
        if (*server) {
            ESP_LOGI(TAG, "Stopping webserver");
            stop_webserver(*server);
            *server = NULL;
        }
    }
    
    //联网处理程序
    static void connect_handler(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data)
    {
        httpd_handle_t* server = (httpd_handle_t*) arg;
        if (*server == NULL) {
            ESP_LOGI(TAG, "Starting webserver");
            *server = start_webserver();
        }
    }
    
    //入口
    void app_main(void)
    {
        static httpd_handle_t server = NULL;
    
        ESP_ERROR_CHECK(nvs_flash_init());
        ESP_ERROR_CHECK(esp_netif_init());
        ESP_ERROR_CHECK(esp_event_loop_create_default());
    
    
        ESP_ERROR_CHECK(example_connect());
    
        /* 
         * 注册事件处理服务,当断开网络时停止服务,当连接网络时重启
         */
    #ifdef CONFIG_EXAMPLE_CONNECT_WIFI
        //连接wifi
        ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &connect_handler, &server));
        ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_STA_DISCONNECTED, &disconnect_handler, &server));
    #endif 
    
    #ifdef CONFIG_EXAMPLE_CONNECT_ETHERNET
        //连接以太网
        ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_ETH_GOT_IP, &connect_handler, &server));
        ESP_ERROR_CHECK(esp_event_handler_register(ETH_EVENT, ETHERNET_EVENT_DISCONNECTED, &disconnect_handler, &server));
    #endif 
    
        //启动服务
        server = start_webserver();
    }

    需要包含的文件:https://gitee.com/EspressifSystems/esp-idf/tree/master/examples/common_components/protocol_examples_common

    原文:https://gitee.com/EspressifSystems/esp-idf

  • 相关阅读:
    loadrunner中变量和参数之间的转化实例
    Web Tours自带示例网站无法打开的解决方案
    LoadRunner替换字符串(可以同时替换多个)
    strcmp函数使用总结
    MVC生成CheckBoxList并对其验证
    MEF(Managed Extensibility Framework)有选择性地使用扩展组件
    MEF(Managed Extensibility Framework)使用全部扩展组件
    委托、多播委托、泛型委托Func,Action,Predicate,ExpressionTree
    使用jQuery异步传递Model到控制器方法,并异步返回错误信息
    使用jQuery异步传递含复杂属性及集合属性的Model到控制器方法
  • 原文地址:https://www.cnblogs.com/kerwincui/p/13958590.html
Copyright © 2011-2022 走看看