嵌入式 Web 后端

一、嵌入式 Web 服务器选型

协议 大小 性能 备注
Mongoose HTTP/MQTT/WebSocket 200KB 单文件、最易用
Civetweb HTTP/HTTPS 1MB C,常用
mongoose-iot 同上 嵌入式 商业版
microhttpd HTTP 500KB GNU
libuv + http HTTP 1MB 需自己写

二、Mongoose 入门

1. 集成

#include "mongoose.h"

2. 简单 HTTP 服务

static void fn(struct mg_connection *c, int ev, void *ev_data)
{
    if (ev == MG_EV_HTTP_MSG) {
        struct mg_http_message *hm = ev_data;
        if (mg_match(hm->uri, mg_str("/api/hello"), NULL)) {
            mg_http_reply(c, 200, "Content-Type: application/json\r\n",
                          "{\"msg\":\"hello\"}");
        } else if (mg_match(hm->uri, mg_str("/"), NULL)) {
            // 返回静态文件
            struct mg_http_serve_opts opts = { .root_dir = "/var/www" };
            mg_http_serve_file(c, hm, "/var/www/index.html", &opts);
        }
    }
}

int main(void)
{
    struct mg_mgr mgr;
    mg_mgr_init(&mgr);
    mg_http_listen(&mgr, "http://0.0.0.0:8080", fn, NULL);
    for (;;) mg_mgr_poll(&mgr, 1000);
    mg_mgr_free(&mgr);
    return 0;
}

3. HTTPS

struct mg_tls_opts opts = { .cert = mg_str_p(server_cert), .key = mg_str_p(server_key) };
mg_http_listen(&mgr, "https://0.0.0.0:8443", fn, &opts);

4. WebSocket

if (ev == MG_EV_WS_MSG) {
    struct mg_ws_message *wm = ev_data;
    mg_ws_send(c->fd, wm->data.buf, wm->data.len, MG_WS_OP_TEXT);
}

三、Civetweb

1. 安装

apt install libcivetweb-dev

2. API

#include "civetweb.h"

static int handler(struct mg_connection *c, void *cbdata)
{
    mg_printf(c, "HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\n\r\nHello\n");
    c->is_resp = 0;
    return 1;
}

int main(void)
{
    struct mg_context *ctx = mg_start(NULL, NULL, NULL);
    mg_set_request_handler(ctx, "/hello", handler, NULL);
    getchar();
    mg_stop(ctx);
}

四、自定义 CGI

if (mg_match(hm->uri, mg_str("/api/sensor"), NULL)) {
    if (hm->method.len == 4 && !memcmp(hm->method.buf, "GET", 3)) {
        float temp = read_temperature();
        char json[64];
        snprintf(json, sizeof(json), "{\"temp\":%.2f}", temp);
        mg_http_reply(c, 200, "Content-Type: application/json\r\n", "%s", json);
    }
}

五、JSON 响应

cJSON *root = cJSON_CreateObject();
cJSON_AddStringToObject(root, "status", "ok");
cJSON_AddNumberToObject(root, "temperature", 25.6);
char *out = cJSON_PrintUnformatted(root);
mg_http_reply(c, 200, "Content-Type: application/json\r\n", "%s", out);
free(out);
cJSON_Delete(root);

六、CORS

mg_http_reply(c, 200,
    "Content-Type: application/json\r\n"
    "Access-Control-Allow-Origin: *\r\n"
    "Access-Control-Allow-Methods: GET,POST\r\n"
    "Access-Control-Allow-Headers: Content-Type\r\n",
    "...");

七、MQTT + HTTP 网关

// HTTP 接收 → MQTT 发布
mg_http_reply(c, 200, "...", "OK");
mqtt_publish("cmd/light", buf, len);

八、设备配置 Web

// SSID 扫描
system("iwlist wlan0 scan > /tmp/scan.txt");
// 解析
// ...
mg_http_reply(c, 200, "...", "<html>...</html>");

九、嵌入式 REST 框架

十、性能

十一、文件传输

// 上传
mg_http_upload(c, hm, "/var/uploads", 100*1024*1024);  // 100MB

// 静态资源
mg_http_serve_dir(c, hm, &opts);

十二、安全