libwebsockets 全文搜索(FTS)HTTP 服务器实战:构建与剖析 minimal-http-server-fulltext-search
人工智能AI Agent多模态语音AI 应用【免费下载链接】ten-frameworkOpen-source framework for conversational voice AI agents项目地址https://gitcode.com/TEN-framework/ten-framework点击查看免费下载本篇指南以 libwebsockets 官方最小示例minimal-http-server-fulltext-search为核心讲解如何构建、运行一个内置全文检索能力的 HTTP 服务器并深入剖析其背后的 lws FTSFull Text Search索引与查询机制。读完本文你将掌握该示例的编译运行方式、前端自动补全与结果展示的交互流程、lws_fts_*公共 API 的用法以及 on-disk 索引文件的格式设计可直接参考本仓库示例搭建自己的轻量全文搜索服务。示例概览一个自带全文搜索的 HTTP 服务器该示例位于仓库的 third_party/libwebsockets/minimal-examples/http-server/minimal-http-server-fulltext-search 目录。它的目标非常具体用 libwebsockets 启动一个 HTTP 服务器将 Oscar Wilde《The Picture of Dorian Gray》全文共 8904 行作为检索语料通过一个网页前端提供边输入边补全、命中行原文展示的全文搜索体验。目录结构如下文件作用minimal-http-server.c服务器主程序创建 context、挂载静态目录与/fts动态协议CMakeLists.txt构建脚本显式检查LWS_WITH_FTS等编译选项lws-fts.index预先生成的 FTS 索引文件trie 序列化产物the-picture-of-dorian-gray.txt搜索语料小说全文mount-origin/静态页面资源index.html、lws-fts.js、lws-fts.css等plugins/protocol_fulltext_demo.c全文字搜索协议插件处理/a/自动补全与/r/查询结果请求构建cmake 与 make原文档给出的构建方式非常简洁$ cmake . make当前仓库内对应的 CMakeLists.txt 揭示了该示例的真实编译前提——libwebsockets 在编译时必须开启三个特性否则构建会被require_lws_config检查拦截require_lws_config(LWS_ROLE_H1 1 requirements) # HTTP/1 角色 require_lws_config(LWS_WITH_FTS 1 requirements) # 全文搜索组件 require_lws_config(LWS_WITH_SERVER 1 requirements) # 服务器能力也就是说构建 libwebsockets 本身时需要开启LWS_WITH_FTScmake 配置项本示例依赖的 FTS 功能才可用。构建成功后会生成可执行文件lws-minimal-http-server-fulltext-search。注意CMakeLists.txt中通过include_directories(../../../plugins)把插件目录加入头文件搜索路径主程序里正是以#include protocol_fulltext_demo.c的方式静态引用插件源码对应源码见 minimal-http-server.c。运行与访问端口 7681构建完成后按原文档运行$ ./lws-minimal-http-server [2018/03/04 09:30:02:7986] USER: LWS minimal http server | visit http://localhost:7681 [2018/03/04 09:30:02:7986] NOTICE: Creating Vhost default port 7681, 1 protocols, IPv6 on然后浏览器访问 http://localhost:7681 即可。启动日志的两行含义USER行是示例自身的欢迎提示告知访问地址NOTICE行来自 libwebsockets 核心说明已创建名为default的 vhost监听端口 7681启用 IPv6。服务器主程序的关键配置见 minimal-http-server.cmemset(info, 0, sizeof info); info.port 7681; info.mounts mount; // 静态目录挂载链 info.protocols protocols; // 含 lws-test-fts 协议 info.pvo pvo; // 协议私有选项indexpath info.options LWS_SERVER_OPTION_HTTP_HEADERS_SECURITY_BEST_PRACTICES_ENFORCE;静态挂载URL 根路径/映射到./mount-origin目录默认文件index.htmlLWSMPRO_FILE动态挂载URL/fts映射到协议lws-test-ftsLWSMPRO_CALLBACK所有全文搜索请求都走这里通过 pvoprotocol vhost options将indexpath指向索引文件路径默认值为./lws-fts.index。前端交互自动补全与命中行展示页面入口 mount-origin/index.html 定义了一个搜索输入框maxlength80和两个结果容器。全部逻辑在 mount-origin/lws-fts.js 中边输入边补全监听输入框的input事件每次输入都发起GET ../fts/a/关键词请求返回以该前缀开头的自动补全建议列表回车出结果输入框获得viable样式即存在有效建议后按 Enter 发起GET ../fts/r/关键词请求展示每个命中文件的行号与命中行原文两个请求都带cache-control: max-age0头禁用缓存确保实时性。前端调用的/a/与/r/两个 URL 子路径正是后端协议插件约定的子目录选择任务约定见下文。后端协议剖析一次搜索请求的完整链路所有搜索请求最终落在协议插件 plugins/protocol_fulltext_demo.c 中。核心是callback_fts回调关键分支如下1. 协议初始化LWS_CALLBACK_PROTOCOL_INIT从 pvo 读取indexpath参数并存入 vhost 私有数据vhd lws_protocol_vh_priv_zalloc(...); if (lws_pvo_get_str(in, indexpath, (const char **)vhd-indexpath)) return 1;若读取失败则初始化失败协议不可用。2. HTTP 请求分发LWS_CALLBACK_HTTPif (strncmp(ccp, /a/, 3) strncmp(ccp, /r/, 3)) goto reply_404; params.needle ccp 3; // 关键词在第三个字符之后 if (*(ccp 1) a) // /a/ 自动补全 params.flags LWSFTS_F_QUERY_AUTOCOMPLETE; if (*(ccp 1) r) // /r/ 查询结果 params.flags LWSFTS_F_QUERY_FILES | LWSFTS_F_QUERY_FILE_LINES | LWSFTS_F_QUERY_QUOTE_LINE; params.max_autocomplete 10; params.max_files 10;然后执行一次完整的打开索引 - 搜索 - 关闭流程jtf lws_fts_open(vhd-indexpath); result lws_fts_search(jtf, params); lws_fts_close(jtf);搜索结果是分配在lwsac内存块分配器中的从result-autocomplete_head与result-filepath_head拿到两条链表头之后在LWS_CALLBACK_HTTP_WRITEABLE中分多次、按 2KB 缓冲流式序列化为 JSON 返回给前端。搜索结束后用lwsac_free释放结果内存LWS_CALLBACK_CLOSED_HTTP分支。3. JSON 输出格式自动补全项输出{ac: ..., matches: N, agg: N, elided: N}其中agg是该前缀路径下所有后代命中的聚合数用于排序最可能结果文件命中项输出{path: ..., matches: N, origlines: N, hits: [{l: 行号, o: 行起始偏移, s: 命中行原文}]}。若索引文件打不开则输出{indexed: 0, ...}前端据此显示没有索引的提示索引构建中则由 JS 轮询并展示进度条。FTS 公共 API 与查询选项libwebsockets 的全文搜索接口集中在 include/libwebsockets/lws-fts.h分为索引创建与索引搜索两组索引创建侧写索引函数作用lws_fts_create(int fd)初始化新索引文件返回struct lws_fts *lws_fts_file_index(t, filepath, len, priority)为每个输入文件登记 filepath返回其序号lws_fts_fill(t, file_index, buf, len)逐缓冲块索引输入文件内容lws_fts_serialize(t)将所有输入处理完后把内存 trie 序列化写入索引文件lws_fts_destroy(trie)结束写入并释放内存 trie索引搜索侧读索引函数作用lws_fts_open(filepath)打开现有索引文件返回struct lws_fts_file *失败返回 NULLlws_fts_search(jtf, params)执行搜索结果分配在params.results_head指向的 lwsac 中lws_fts_close(jtf)关闭索引文件并释放相关分配查询标志params.flags组合#define LWSFTS_F_QUERY_AUTOCOMPLETE (1 0) // 返回自动补全建议 #define LWSFTS_F_QUERY_FILES (1 1) // 返回命中文件列表 #define LWSFTS_F_QUERY_FILE_LINES (1 2) // 每个文件附带行号行起始偏移 #define LWSFTS_F_QUERY_QUOTE_LINE (1 3) // 额外附带命中行原文最多255字符struct lws_fts_search_params关键成员needle检索词、only_filepath限定单文件检索、flags、max_autocomplete、max_files、max_lines每个文件最多返回多少行结果。三种结果形态与示例的对应关系自动补全/a/、文件列表/r/的fp段、文件行号原文/r/的hits段。调用前应将params整体memset为 0避免后续版本新增成员包含未知值。索引原理内存 trie 与磁盘序列化lws FTS 的整体设计在 third_party/libwebsockets/lib/misc/fts/README.md 中有完整说明实现代码位于 lib/misc/fts/trie.c 与 lib/misc/fts/trie-fd.c。核心思路扫描一个或多个 UTF-8 文本文件可以是纯内存数据为每个 token 构建内存优化的trie前缀树无论输入文件多少、体量多大最终序列化为单一索引文件搜索时只需读入结果内存通过在磁盘索引文件中快速 seek完成检索与自动补全对弱性能设备带随机访问存储友好。内存中的 trie 节点包含大量额外指针与大类型字段而序列化后的文件大量采用VLI变长整数编码按值大小伸缩占字节因此大语料的峰值内存占用远高于最终索引文件体积。序列化完成后查询成本极低子节点按字符排序可提前判定无匹配根 trie 额外附带 256 项指针表实现一步定位该表约 2KiB过大故仅根节点使用。文档还给出了同条件下的实测参考数据来自 libwebsockets 项目文档非本仓库评测索引 Linux 4.14 内核源码默认文件列表时52932 个文件、694MiB 语料索引耗时约 50.1s约 13.8MB/s峰值分配约 78MiB序列化耗时约 202mstrie 文件约 347MiB索引 libwebsockets 自身 main 分支489 文件、3MiB时索引耗时约 123ms峰值约 3MiBtrie 文件约 1.4MiB。磁盘索引文件格式lws-fts.index遵循固定布局详见 lib/misc/fts/README.md 的 Structure on disk 一节文件头16 字节定长Magic0xCA7A5F75、根 trie 条目 fileoffset、创建时 trie 文件大小用于检测截断、filepath map 的 fileoffset、filepath 数量Filepath 行表每文件按块记录各行字节长度块头 8 字节本块长度、覆盖行数、覆盖输入字节数末尾全零块标记结束支持快速跳跃定位逻辑行号Filepaths每个文件一条记录行表起始偏移、总行数、文件名字节长度、文件名字符串Filepath map每文件一个 32-bit 偏移表用于把文件序号快速转换为文件信息Trie 条目条目头含首实例文件表偏移、子条目数、实例数三个 VLI其后是该条目的文件实例表下一实例文件偏移、filepath 序号、行号实例数、升序行号表、子表子偏移、直接实例数、后代聚合实例数、后代聚合子数、匹配串长度、匹配串。除少数需事后回填的数字外全部使用 VLI 编码多字节数字按网络字节序MSB first。VLI 规则字节最高位为 EON 标志0表示数据结束、低 7 位即数值1表示后续字节为更高位。例如0x30 48、0x81 0x30 176、0x81 0x80 0x00 16384。由于行号通常小于 16K2 字节即可表示这种编码对行号类小数值极其紧凑。本示例在仓库中的定位libwebsockets 以 submodule/third_party 形式随本仓库提供见 third_party/BUILD.gn 等构建入口本示例属于其minimal-examples中的 http-server 演示集合是 FTS 功能的官方最小可运行展示。它的价值在于完整的构建配置、预生成的lws-fts.index、可离线运行的语料与前端让开发者无需任何额外数据即可体验并理解 libwebsockets 全文搜索的完整工作链路。从 plugins/protocol_fulltext_demo.c 头部注释可以看出该插件以 Public DomainCC0许可提供明确意在让你改编进自己的可能专有的代码是学习与复用的直接模板。若要在自己的项目中复用参考路径是用lws_fts_create/lws_fts_file_index/lws_fts_fill/lws_fts_serialize建立索引文件再在 HTTP 协议回调中用lws_fts_open/lws_fts_search/lws_fts_close响应搜索请求最后用lwsac_free释放结果——这正是本示例用 200 余行 C 代码演示的完整闭环。赞分享人工智能AI Agent多模态语音AI 应用【免费下载链接】ten-frameworkOpen-source framework for conversational voice AI agents项目地址https://gitcode.com/TEN-framework/ten-framework点击查看免费下载相关推荐基于 libwebsockets 构建最小 HTTP 服务器minimal-http-server 示例全解析TEN-framework 集成视角基于 libwebsockets 构建最小 HTTP 服务器minimal http server 示例全解析TEN framework 集成视角 导读人工智能AI Agent多模态语音AI 应用libwebsockets 多 vhost HTTP 服务器实战基于 Host 头路由的 minimal-http-server-multivhost 深度解析libwebsockets 多 vhost HTTP 服务器实战基于 Host 头路由的 minimal http server multivhost 深度解人工智能AI Agent多模态语音AI 应用基于 libwebsockets 的最小化 HTTPS 服务器minimal-http-server-tls 实战与源码解析基于 libwebsockets 的最小化 HTTPS 服务器minimal http server tls 实战与源码解析 本指南以 TEN framewo人工智能AI Agent多模态语音AI 应用上一篇《经济研究》LaTeX模板终极指南从零基础到学术达人的完美蜕变下一篇3步搞定SD模型下载告别慢速和复杂配置的终极方案创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

Sandstorm Activity Events 平台 API 深度解析:活动指示、通知分发与订阅机制

Sandstorm Activity Events 平台 API 深度解析:活动指示、通知分发与订阅机制

后端容器运行时安全云原生 【免费下载链接】sandstorm Sandstorm is a self-hostable web productivity suite. Its implemented as a security-hardened web app package manager. | Actively sponsored by our friends at TestMu AI 项目地址: https://gitcode.co…

2026/10/11 0:31:51 阅读更多 →
Beaker Browser 应用源码结构解析:Electron 入口、进程架构与构建调试指南

Beaker Browser 应用源码结构解析:Electron 入口、进程架构与构建调试指南

前端 【免费下载链接】beaker An experimental peer-to-peer Web browser 项目地址: https://gitcode.com/gh_mirrors/be/beaker 点击查看 免费下载 本文以仓库根目录 app/README.md 为骨架,结合 app 目录下实际源码,系统梳理 Beaker Browse…

2026/10/10 5:40:49 阅读更多 →
KubeVirt 中的 go-openapi/strfmt:OpenAPI 字符串格式注册表与校验机制深度解析

KubeVirt 中的 go-openapi/strfmt:OpenAPI 字符串格式注册表与校验机制深度解析

云原生 【免费下载链接】kubevirt Kubernetes Virtualization API and runtime in order to define and manage virtual machines. 项目地址: https://gitcode.com/gh_mirrors/ku/kubevirt 点击查看 免费下载 导读:本文围绕 KubeVirt 仓库中随依赖一起 …

2026/10/9 10:24:59 阅读更多 →

最新新闻

太阳能电池板YOLO高变焦检测:24577张数据集训练实战

太阳能电池板YOLO高变焦检测:24577张数据集训练实战

简介:面向太阳能光伏板检测与YOLO模型训练的实际需求,这份压缩包针对高变焦太阳能电池板图像场景,提供了带有标签的光伏板检测标注数据集,能帮助开发者和研究人员快速获得规范标注样本,降低从图像采集、清洗到标注的重…

2026/10/11 0:31:53 阅读更多 →
GANMaster人脸矫正实战:从模糊脸到公安标准证件照

GANMaster人脸矫正实战:从模糊脸到公安标准证件照

简介:本资源是一份面向深度学习初学者与计算机视觉实践者的GAN人脸生成与矫正实战教程,聚焦生成对抗网络原理落地与Python代码实现。资源包含4个核心文件(2个Python脚本、1份Markdown说明文档、1份LICENSE),总大小仅9K…

2026/10/11 0:31:53 阅读更多 →
FCOM参考PDF解析:从性能表到插值函数的工程化指南

FCOM参考PDF解析:从性能表到插值函数的工程化指南

简介:这是一份面向飞行机组、飞行学员及航空爱好者的FCOM(飞行操作手册)参考指南,聚焦B737机型日常运行中的关键操作程序与处置规范。内容涉及驾驶舱区域分工、起降标准动作、着陆后刹车冷却表查算、放行与天气及杰普逊资料认读、…

2026/10/11 0:31:52 阅读更多 →
Spring Boot实战:智慧养老院管理系统的架构设计与权限控制

Spring Boot实战:智慧养老院管理系统的架构设计与权限控制

从需求到落地:我如何用Spring Boot搭起一套智慧养老院管理系统去年年初接手了一个养老院管理系统的开发任务,机构那边的情况比较典型:三百多张床位,护理人员几十号人,老人的健康档案还停留在纸质登记,家属想…

2026/10/11 0:31:52 阅读更多 →
端侧AI导览实战:鸿蒙+蓝耘MaaS的离线多模态落地

端侧AI导览实战:鸿蒙+蓝耘MaaS的离线多模态落地

1. 项目概述:这不是一个App,而是一次端侧AI能力的现场压力测试“鸿蒙AI:国庆我在故宫用了把‘AI 导游’”——这个标题里藏着三个被大众忽略但极其关键的信号:时间(国庆)、空间(故宫&#xff09…

2026/10/11 0:31:52 阅读更多 →
PLC动态加密功能块实战:S7-1200/1500程序防复制与授权管理

PLC动态加密功能块实战:S7-1200/1500程序防复制与授权管理

干自动化这些年,最扎心的场景不是现场调试到凌晨,而是设备刚交出去半年,就发现客户厂里多了一台和你做的设备一模一样的机器,运行逻辑连定时器参数都没改。S7-1200/1500 在国内项目里太常见,上载、反编译、复制项目的门…

2026/10/11 0:30:51 阅读更多 →

日新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/11 0:00:27 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/11 0:00:27 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/11 0:00:27 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/11 0:00:27 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/11 0:00:27 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/11 0:00:27 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/10 5:23:50 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/9 21:32:20 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/10 10:38:42 阅读更多 →