《Linux操作系统编程详解》《笔试/面试常见算法:从基础到进阶》《Python干货分享》
🎬 艾莉丝的简介:
文章目录
- 1 ~> ChatServer 路由规则绑定
- 1.1 业务背景
- 1.2 类定义扩展
- 1.2.1 结构体与类完整声明
- 1.3 路由规则实现 setHttpRoutes
- 1.3.1 源文件实现代码
- 1.4 路由绑定函数调用时机
- 1.4.1 核心约束
- 1.4.2 start () 完整实现(含静态资源挂载)
- 2 ~> httplib 静态资源挂载
- 2.1 静态资源概念
- 3 ~> 开发规范与面试要点
- 3.1 路由开发规范
- 3.2 调用时序重点(面试高频)
- 3.3 线程模型说明
- 3.4 REST API 设计对应关系汇总表
- 4 ~> 易错点总结
- 结尾
1 ~> ChatServer 路由规则绑定
1.1 业务背景
- ChatServer 已经完成 7 个业务处理成员方法的编码实现。
- 核心问题:HTTP 客户端发起网络请求,服务器如何将收到的请求分发到对应的业务处理函数。
- 解决方案:配置 HTTP 路由绑定规则,建立「HTTP 请求 (请求方法 + URI 路径)」与「类成员处理函数」映射关系。
- 开发最佳实践:实现一个业务处理方法,立刻绑定一条路由;全部写完再统一绑定极易出现请求与处理函数匹配错误。
- 路由校验三要素(每条路由必须核对)
- HTTP 请求方法(GET/POST/DELETE 等)
- 请求 URI 路径(支持路径占位符,如
/api/session/${session_id}) - 绑定的业务处理回调函数
1.2 类定义扩展
1.2.1 结构体与类完整声明
namespaceai_chat_server{// 服务器配置结构体structServerConfig{std::string chatGPTAPIKey;// chatGPT API Key// ollama大模型配置std::string ollamaModelName;// ollama模型名称std::string ollamaModelDesc;// ollama模型描述std::string ollamaEndpoint;// ollama API地址std::string host;// http服务监听地址uint16_tport;// http服务监听端口};classChatServer{public:ChatServer(constServerConfig&config);~ChatServer();boolstart();// 启动服务器voidstop();// 停止服务器boolisRunning()const;// 查询服务器运行状态private:// 通用响应构造工具函数std::stringbuildResponse(conststd::string&message,boolsuccess=false);// 7个业务请求处理回调函数voidhandleCreateSessionRequest(consthttplib::Request&request,httplib::Response&response);voidhandleGetSessionListsRequest(consthttplib::Request&request,httplib::Response&response);voidhandleGetModelListsRequest(consthttplib::Request&request,httplib::Response&response);voidhandleDeleteSessionRequest(consthttplib::Request&request,httplib::Response&response);voidhandleGetHistoryMessagesRequest(consthttplib::Request&request,httplib::Response&response);voidhandleSendMessageRequest(consthttplib::Request&request,httplib::Response&response);voidhandleSendMessageStreamRequest(consthttplib::Request&request,httplib::Response&response);// 新增:HTTP路由规则绑定函数voidsetHttpRoutes();private:ServerConfig _config;// 服务器配置信息std::unique_ptr<httplib::Server>_chatServer;// httplib HTTP服务实例std::shared_ptr<ai_chat_sdk::ChatSdk>_chatSdk;// chat sdk实例std::atomic<bool>_isRunning{false};// 服务运行状态原子变量};}1.3 路由规则实现 setHttpRoutes
1.3.1 源文件实现代码
使用 httplib 库,捕获
this指针,lambda 内部调用类的私有成员处理函数;lambda 参数必须为 const 引用,避免拷贝。
#include"ChatServer.h"namespaceai_chat_server{voidChatServer::setHttpRoutes(){// 1. 创建会话请求 POST /api/session_chatServer->Post("/api/session",[this](consthttplib::Request&request,httplib::Response&response){handleCreateSessionRequest(request,response);});// 2. 获取会话列表 GET /api/sessions_chatServer->Get("/api/sessions",[this](consthttplib::Request&request,httplib::Response&response){handleGetSessionListsRequest(request,response);});// 3. 获取模型列表 GET /api/models_chatServer->Get("/api/models",[this](consthttplib::Request&request,httplib::Response&response){handleGetModelListsRequest(request,response);});// 4. 删除会话 DELETE /api/session/{session_id}_chatServer->Delete("/api/session/{session_id}",[this](consthttplib::Request&request,httplib::Response&response){handleDeleteSessionRequest(request,response);});// 5. 获取会话历史消息 GET /api/session/{session_id}/history_chatServer->Get("/api/session/{session_id}/history",[this](consthttplib::Request&request,httplib::Response&response){handleGetHistoryMessagesRequest(request,response);});// 6. 发送消息【全量返回】 POST /api/message_chatServer->Post("/api/message",[this](consthttplib::Request&request,httplib::Response&response){handleSendMessageRequest(request,response);});// 7. 发送消息【流式增量返回】 POST /api/message/async_chatServer->Post("/api/message/async",[this](consthttplib::Request&request,httplib::Response&response){handleSendMessageStreamRequest(request,response);});}}1.4 路由绑定函数调用时机
1.4.1 核心约束
- 必须在
listen()监听启动之前完成路由绑定;一旦服务开始监听接收客户端请求,后续新增路由不会生效。 - 在
ChatServer::start()启动函数内部调用setHttpRoutes()。 - http 服务运行在独立子线程,防止阻塞主线程;使用
detach()分离线程。
1.4.2 start () 完整实现(含静态资源挂载)
namespaceai_chat_server{boolChatServer::start(){// 原子变量判断服务是否已经运行if(_isRunning.load()){ERR("ChatServer is running!!!");returnfalse;}// 【第一步】绑定全部HTTP路由规则,listen之前执行setHttpRoutes();// 【第二步】设置静态资源挂载点// mount_point="/" 代表http根路径映射到磁盘 ./www目录// 浏览器访问 http://ip:port 会自动寻找 ./www/index.html_chatServer->set_mount_point("/","./www");// 启动独立线程运行http服务,避免阻塞主线程std::threadserverThread([this](){INFO("ChatServer start on {}:{}",_config.host,_config.port);_chatServer->listen(_config.host,_config.port);});// 线程分离,后台运行serverThread.detach();// 修改运行状态标记_isRunning.store(true);INFO("ChatServer start success!!!");returntrue;}voidChatServer::stop(){if(!_isRunning.load()){ERR("ChatServer is not running!!!");return;}if(_chatServer){_chatServer->stop();}_isRunning.store(false);}}2 ~> httplib 静态资源挂载
2.1 静态资源概念
- 静态资源:网页 html、css、js、图片等不需要后端动态计算,直接返回磁盘文件的资源。
set_mount_point(mount_point, dir)接口说明mount_point:http 访问 url 前缀路径,"/"代表 http 根路径。dir:磁盘本地目录路径,示例./www,代表可执行程序 exe 同级目录下的 www 文件夹。
- 默认首页行为:httplib 库,当浏览器仅访问
http://ip:port不带资源路径时,库内部自动查找index.html作为默认返回页面。 - 前端页面开发约定:前端入口页面固定命名为
index.html,放置到./www目录。
3 ~> 开发规范与面试要点
3.1 路由开发规范
- 开发顺序:写完 1 个业务处理函数,立刻绑定 1 条路由,不要全部写完再批量绑定。
- 每条路由校验三项:HTTP 方法、URI 路径、回调处理函数。
- 路径占位符语法:
{param_name},httplib 可以自动捕获 url 路径中的参数。 - lambda 捕获:
[this]捕获类实例指针,才可以调用私有成员方法;参数必须使用引用&,避免请求对象拷贝。
3.2 调用时序重点(面试高频)
- ChatServer 构造函数:创建
httplib::Server实例。 - 调用
ChatServer::start()- 判断服务运行状态。
- 执行
setHttpRoutes()绑定全部路由。 - 执行
set_mount_point()挂载静态资源目录。 - 创建子线程,子线程内部执行
_chatServer->listen()开启端口监听。
- listen 之后,服务器接收客户端 http 请求,根据已经注册的路由分发到对应回调函数。
3.3 线程模型说明
- httplib 的
listen()是阻塞接口,如果直接在主线程调用会阻塞整个程序。 - 将 listen 放置子线程,使用 detach 分离,实现后台 http 服务,主线程可以继续执行其他业务逻辑。
- 使用
std::atomic<bool>原子变量保存_isRunning状态,保证多线程环境下状态读取写入线程安全。
3.4 REST API 设计对应关系汇总表
| 请求方法 | URI 路径 | 处理回调函数 | 功能说明 |
|---|---|---|---|
| POST | /api/session | handleCreateSessionRequest | 创建会话 |
| GET | /api/sessions | handleGetSessionListsRequest | 获取会话列表 |
| GET | /api/models | handleGetModelListsRequest | 获取模型列表 |
| DELETE | /api/session/{session_id} | handleDeleteSessionRequest | 删除指定会话 |
| GET | /api/session/{session_id}/history | handleGetHistoryMessagesRequest | 获取会话历史消息 |
| POST | /api/message | handleSendMessageRequest | 发送消息,全量一次性返回 |
| POST | /api/message/async | handleSendMessageStreamRequest | 发送消息,流式增量返回 |
4 ~> 易错点总结
- 在 listen () 监听之后才调用 setHttpRoutes (),路由不会生效。
- lambda 参数不写引用,造成 Request/Response 对象拷贝,响应失效。
- 忘记捕获
[this],lambda 无法访问类成员函数。 - 静态资源目录写错,浏览器访问无法加载 index.html 页面。
- 不使用 atomic保存运行状态,多线程下发生数据竞争。
结尾
uu们,本文的内容到这里就全部结束了,艾莉丝在这里再次感谢您的阅读!
|
结语:希望对学习Linux相关内容的uu有所帮助,不要忘记给博主“一键四连”哦!
往期回顾:
【AI大模型接入SDK】ChatServer接口实现
🗡博主在这里放了一只小狗,大家看完了摸摸小狗放松一下吧!🗡 ૮₍ ˶ ˊ ᴥ ˋ˶₎ა