基于Nginx轻量级嵌入式Web前后端框架搭建
目录
基于Nginx轻量级嵌入式Web前后端框架搭建
基于Nginx轻量级嵌入式Web前后端框架搭建
1 项目概述
本项目基于Nginx和FastCGI实现了一个轻量级嵌入式Web前后端框架,支持用户权限管理、设备状态监控、远程控制等功能。前端采用TypeScript+HTML开发,后端使用C/C++实现,前后端通过FastCGI协议通信。
项目源码:
2 核心特性
a. 设备监控与控制(未实现)
- 实时监控设备状态
- 远程控制智能设备
b. 用户管理
- 基于htpasswd的用户认证系统
- 细粒度权限控制
c. 响应式设计(未实现)
- 适配不同终端设备
- 现代化UI交互体验
3 技术架构
3.1 前端技术栈
- TypeScript
- Webpack构建工具
- Bootstrap响应式框架
- FastCGI通信协议
3.2 后端技术栈
- C/C++高性能实现
- Nginx 1.14.0 Web服务器
- FastCGI后端服务
4 开发环境配置
4.1 系统要求
- CMake ≥ 3.10
- GCC/G++编译器
- Node.js ≥ 22.17.1
- Nginx 1.14.0
4.2 环境初始化
# 安装基础依赖
sudo apt-get install libssl-dev
# 克隆项目
git clone https://gitcode.com/aiprtem_iot/tinyweb_nginx.git
# 设置环境变量
source envsetup
5 构建与部署
5.1 构建流程
a. 预构建依赖
meprebuild
b. 主构建
mebuild
c. 打包发布
mepack
d. 系统安装
sudo meinstall
PS: 程序会默认安装到“/opt/webserver/`目录下。
5.2 服务管理
启动服务
可以通过/opt/webserver/scripts/目录下的脚本启动服务。
# FastCGI后端
./fcgiServer.sh start
# Nginx前端
./nginxd.sh start
停止服务
./fcgiServer.sh stop
./nginxd.sh stop
6 开发指南
6.1 目录结构
tinyweb/ # 前端项目
webserver/ # 后端实现
├── doc/ # 文档
├── prebuilt/ # 预构建依赖
├── scripts/ # 服务控制脚本
├── src/ # 源代码
└── test/ # 测试代码
6.2 扩展开发
a. 新增API接口
- 在
webserver/src/
中添加FastCGI处理模块
功能概述
b. 服务器初始化
- 全局变量管理(如
cgi_sock
)和信号处理(如cleanup_handler
)。 - 支持守护进程和停止模式。
c. 请求处理
- JSON 请求解析(如
web_process_login
)。 - 业务逻辑实现(登录等)。
d. 接口配置
- 套接字路径(
FCGI_SOCKET_PATH
)。 - 线程数和日志文件设置。
- 更新Nginx配置
e. 前端功能扩展
- 在
tinyweb/src/
中添加TypeScript模块 - 通过Webpack打包
7 登录模块实现
7.1 接口设计
登录接口
// 从项目源码中提取的实际接口定义
{
"path": "/api/v1/auth/login",
"method": "POST",
"request": {
"username": "string",
"password": "string"
},
"response": {
"token": "string",
"user": {
"id": "string",
"username": "string"
}
}
}
7.2 项目结构框图
部署模块
后端模块
前端模块
Nginx配置
静态文件服务
反向代理
login.ts
API路由
数据库交互
login.html
静态资源
Webpack打包
HTTP请求
响应数据
静态资源
API服务
反向代理
前端模块
后端模块
部署模块
用户访问
7.3 前端实现
登录页面(HTML)
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>用户登录</title>
<style>
body {
font-family: Arial, sans-serif;
background-color: #f5f5f5;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
margin: 0;
}
.login-container {
background: white;
padding: 2rem;
border-radius: 8px;
box-shadow: 0 0 10px rgba(0,0,0,0.1);
width: 300px;
}
h1 {
text-align: center;
color: #333;
margin-bottom: 1.5rem;
}
.form-group {
margin-bottom: 1rem;
}
label {
display: block;
margin-bottom: 0.5rem;
color: #555;
}
input {
width: 100%;
padding: 0.5rem;
border: 1px solid #ddd;
border-radius: 4px;
box-sizing: border-box;
}
button {
width: 100%;
padding: 0.75rem;
background-color: #4CAF50;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 1rem;
}
button:hover {
background-color: #45a049;
}
.error {
color: red;
margin-top: 1rem;
text-align: center;
}
</style>
</head>
<body>
<div class="login-container">
<h1>用户登录</h1>
<form id="loginForm">
<div class="form-group">
<label for="username">用户名</label>
<input type="text" id="username" name="username" required>
</div>
<div class="form-group">
<label for="password">密码</label>
<input type="password" id="password" name="password" required>
</div>
<button type="submit">登录</button>
</form>
<div id="errorMessage" class="error"></div>
</div>
<!-- Script will be automatically injected by webpack -->
</body>
</html>
登录请求RESFUL API接口定义
api:/api/v1/auth/login
// 从tinyweb/src/login.ts提取的接口定义
interface LoginResponse {
token: string;
user: {
id: string;
username: string;
};
}
登录表单实现(TypeScript)
// 从tinyweb/src/login.ts提取的核心逻辑
document.addEventListener('DOMContentLoaded', () => {
const loginForm = document.getElementById('loginForm') as HTMLFormElement;
loginForm.addEventListener('submit', async (e) => {
e.preventDefault();
const username = (document.getElementById('username') as HTMLInputElement).value;
const password = (document.getElementById('password') as HTMLInputElement).value;
const response = await fetch('/api/v1/auth/login', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ username, password })
});
if (response.ok) {
const data: LoginResponse = await response.json();
localStorage.setItem('authToken', data.token);
window.location.href = 'index.html';
}
});
});
7.4 后端实现
7.4.1 FastCGI 服务器初始化
#include "fcgi_server.h"
int cgi_sock = -1;
int daemon_mode = 0; // 默认不以守护进程方式运行
int stop_mode = 0; // 默认不是停止模式
#define PID_FILE "/tmp/fcgiserver.pid"
// Signal handler to clean up socket file on exit
void cleanup_handler(int sig) {
log_info("Received signal %d, cleaning up and exiting...", sig);
if (cgi_sock >= 0) {
close(cgi_sock);
cgi_sock = -1;
}
unlink(FCGI_SOCKET_PATH);
unlink(PID_FILE); // 删除PID文件
log_info("Cleanup complete, exiting");
exit(0);
}
7.4.2 请求处理逻辑
#include "web_login.h"
void web_process_login(fcgxEnvParams *envParams, char *recvBuf, int len) {
// 解析 JSON 请求
struct json_object *infor_object = json_object_new_object();
if (NULL == infor_object) {
log_error("Failed to create JSON object");
return;
}
// 处理登录逻辑
// ...
}
7.4.3 与前端交互的接口定义
#define FCGI_SOCKET_PATH "/var/run/fcgiserver.sock"
#define CGI_THREAD_NUM 4
#define FCGI_SERVER_LOG_FILE_NAME "/tmp/fcgi_server.log"
#define FCGX_URL_STRING_MAX_LEN 10240
**FastCGI处理模块
功能概述
服务器初始化
- 全局变量管理(如
cgi_sock
)和信号处理(如cleanup_handler
)。 - 支持守护进程和停止模式。
- 全局变量管理(如
请求处理
- JSON 请求解析(如
web_process_login
)。 - 业务逻辑实现(登录等)。
- JSON 请求解析(如
接口配置
- 套接字路径(
FCGI_SOCKET_PATH
)。 - 线程数和日志文件设置。©**
- 套接字路径(
8 最佳实践
a. 嵌入式适配
- 修改
webserver/toolchain.cmake
配置交叉编译 - 优化Nginx配置减少内存占用
b. 性能调优
- 启用FastCGI连接池
- 优化SQL查询
9 常见问题
Q: 如何添加新用户?
cd /opt/webserver/bin
./htpasswd -c /root/.webserver/htpasswd 用户名
Q: 如何调试FastCGI服务?
- 启用debug日志级别
- 使用gdb附加到fcgi进程