嵌入式 Web 后端
一、嵌入式 Web 服务器选型
| 库 |
协议 |
大小 |
性能 |
备注 |
| Mongoose |
HTTP/MQTT/WebSocket |
200KB |
高 |
单文件、最易用 |
| Civetweb |
HTTP/HTTPS |
1MB |
中 |
C,常用 |
| mongoose-iot |
同上 |
嵌入式 |
强 |
商业版 |
| microhttpd |
HTTP |
500KB |
中 |
GNU |
| libuv + http |
HTTP |
1MB |
高 |
需自己写 |
二、Mongoose 入门
1. 集成
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 框架
- 比较完整的:Mongoose + cJSON
- 轻量:libuv + 自己实现
- 高级:Civetweb + 路由器 / DB
十、性能
- 单线程 Mongoose:~10k QPS(简单响应)
- epoll + worker:~100k QPS
- HTTPS:性能下降 50%
十一、文件传输
// 上传
mg_http_upload(c, hm, "/var/uploads", 100*1024*1024); // 100MB
// 静态资源
mg_http_serve_dir(c, hm, &opts);
十二、安全
- 鉴权(Token、Basic、Digest)
- HTTPS(TLS)
- 输入验证
- 限速、防 DoS
- 日志审计