ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

TEN Framework 中的 libwebsockets 最小 WS 客户端示例全解析:从重试退避到多连接压测

TEN Framework 中的 libwebsockets 最小 WS 客户端示例全解析:从重试退避到多连接压测 人工智能AI Agent多模态语音AI 应用【免费下载链接】ten-frameworkOpen-source framework for conversational voice AI agents项目地址https://gitcode.com/TEN-framework/ten-framework点击查看免费下载libwebsocketslws是 TEN Framework 构建 WebSocket 通信能力的底层依赖之一在仓库中以 third_party/libwebsockets 的方式集成。本文聚焦 lws 官方 minimal-examples 中ws-client 目录下的 7 个最小客户端示例逐一讲解其用途、构建方式、命令行参数与核心源码实现并延伸到这些客户端能力重试退避、permessage-deflate、多连接并发在 TEN Framework 实际工程中的落地方式。读完本文你将掌握用 lws 实现可断线重连、可压测、可发布/订阅的 WS 客户端的关键编程模式。示例总览ws-client 目录下的 7 个最小客户端在 third_party/libwebsockets/minimal-examples/ws-client/README.md 中lws 官方给出了 7 个最小客户端示例的索引各自的定位如下名称功能定位minimal-ws-client连接到 libwebsockets.org 的 dumb-increment-protocol演示 lws 的连接重试retry与退避backoff机制minimal-ws-client-echo连接到一个 WS 服务器把服务器发来的任何数据原样回显echominimal-ws-client-pingWS Ping 测试客户端验证连接的活性validityminimal-ws-client-pmd-bulk向 minimal-ws-server-pmd-bulk 示例发送多分片multifragment批量数据minimal-ws-client-rx通过 wss 连接 dumb-increment-protocol演示如何接收 WS 数据minimal-ws-client-spam并行向服务器轰炸多个 WS 连接用于稳定性测试minimal-ws-client-tx连接 minimal-ws-broker 示例充当发布者publisher演示发送 WS 数据每个示例都在独立子目录中包含自己的CMakeLists.txt、README.md和.c源文件。所有示例都遵循同一个极简构建流程$ cmake . make基础客户端连接重试与退避机制minimal-ws-clientminimal-ws-client 是所有示例中最具教学价值的一个——它默认连接 libwebsockets.org 的 dumb-increment-protocol服务器以20Hz 频率持续推送递增数字客户端则演示了 lws 连接重试与退避策略的完整用法。命令行参数该示例支持以下命令行选项选项含义-d设置日志详细程度verbosity-s指定目标服务器而非默认的 libwebsockets.org如--server localhost隐含启用LCCSCF_ALLOW_SELFSIGNED-p指定端口而非默认的 443如--port 7681-j允许自签名 TLS 证书-k允许不安全insecure的证书-m跳过服务器主机名校验-n跳过 TLS 使用-e允许已过期证书--protocol指定 WS 子协议而非默认的 dumb-increment-protocol如--protocol myprotocol运行与验证直接运行即可看到服务器推送的递增数字$ ./lws-minimal-ws-client [2020/01/22 05:38:47:3409] U: LWS minimal ws client [2020/01/22 05:38:47:4456] N: Loading client CA for verification ./libwebsockets.org.cer [2020/01/22 05:38:48:1649] U: callback_minimal: established [2020/01/22 05:38:48:1739] N: [2020/01/22 05:38:48:1763] N: 0000: 30 0 ...若希望针对本地测试服务器而非公网服务器先以 TLS 模式启动 lws 测试服务器$ libwebsockets-test-server -s再用-s localhost -p 7681 -j让客户端连接它$ ./lws-minimal-ws-client -s localhost -p 7681 -j关键验证点在退避周期内杀掉并重启服务器客户端连接会被自动重新建立。这正是 lws 重试调度机制lws_retry_sul_schedule_retry_wsi的直接体现。源码级原理重试表与退避策略打开 minimal-ws-client.c可以看到退避策略的完整定义第 37–48 行static const uint32_t backoff_ms[] { 1000, 2000, 3000, 4000, 5000 }; static const lws_retry_bo_t retry { .retry_ms_table backoff_ms, .retry_ms_table_count LWS_ARRAY_SIZE(backoff_ms), .conceal_count LWS_ARRAY_SIZE(backoff_ms), .secs_since_valid_ping 3, /* force PINGs after secs idle */ .secs_since_valid_hangup 10, /* hangup after secs idle */ .jitter_percent 20, };这段代码定义了 lws 重试策略的核心要素retry_ms_table退避时间表首次失败后等 1000ms第二次 2000ms依此类推最多到 5000msconceal_count隐藏conceal次数与表项数量一致时意味着重试完一整轮表格后客户端将放弃示例中interrupted 1并退出程序。源码注释明确指出若将conceal_count设为大于表中元素个数客户端将永不放弃始终以最后退避延迟 随机抖动的频率重试jitter_percent 20每次退避延迟附加 ±20% 的随机抖动避免多个客户端在同一时刻集中重连防止惊群效应secs_since_valid_ping/secs_since_valid_hangup空闲 3 秒后强制发送 PING 探测10 秒未收到有效 PONG 则判定连接失效并断开。连接建立通过lws_client_connect_via_info第 75 行完成失败时调用lws_retry_sul_schedule重新调度第 81 行连接建立后若收到LWS_CALLBACK_CLIENT_CONNECTION_ERROR或LWS_CALLBACK_CLIENT_CLOSED则走do_retry分支调用lws_retry_sul_schedule_retry_wsi第 130 行继续按退避表重试从而保证连接一直钉住nailed up。这是 lws 客户端工程化最值得借鉴的模式把连接的生命周期交给 lws 的 SULsorted usc list调度器管理而不是自己写循环重连。回显客户端permessage-deflate 与 Autobahn 测试minimal-ws-client-echominimal-ws-client-echo 默认连接localhost:7681将服务器发来的任何内容原样回显。官方用途是配合 Autobahn 测试套件检验 lws 的 WS 协议符合性。命令行参数选项含义-d loglevel十进制日志级别如-d15-p port连接端口-u url连接的 URL 路径部分-o完成一次连接后即结束--ssl以 SSL 建立客户端连接-i iface将客户端连接绑定到指定网卡接口从 minimal-ws-client-echo.c 可以看到两个值得注意的工程细节permessage-deflate 扩展通过struct lws_extension数组显式注册第 79–88 行携带client_no_context_takeover与client_max_window_bits参数命令行加-n时则跳过info.extensions从而关闭压缩扩展通过struct lws_protocol_vhost_optionspvo链表把共享变量端口、地址、URL、中断标志等注入协议层这是 lws 中向协议回调传递自定义配置的标准手法上下文创建时设置LWS_SERVER_OPTION_VALIDATE_UTF8并利用info.fd_limit_per_thread 1 1 1告知 lws 只需为 1 个内部 fd、1 个连接及 1 个 http2 nwsi 分配表项注释中明确说明这是为单个客户端连接场景减少默认的 fd 表内存分配。活性探测客户端Validity PING/PONGminimal-ws-client-pingminimal-ws-client-ping 使用 lws-mirror-protocol 连接 libwebsockets.org演示连接活性校验每3 秒发送一次 PING 探测若10 秒内未收到 PONG 则判定连接失效。这两个数字与上一节minimal-ws-client中lws_retry_bo_t的secs_since_valid_ping/secs_since_valid_hangup完全对应说明PING 保活 PONG 超时判死是 lws 客户端连接活性校验的统一机制。命令行选项与基础客户端类似-d设置日志级别想看 PING/PONG 过程官方建议-d1039--server/--port/--protocol分别指定服务器、端口与子协议。运行日志中可以看到完整的活性探测生命周期源码运行日志见 README[2020/03/18 13:13:48:5197] I: _lws_validity_confirmed_role: wsi 0x5669090: setting validity timer 3s (hup 0) [2020/03/18 13:13:51:5218] I: lws_validity_cb: wsi 0x5669090: scheduling validity check [2020/03/18 13:13:51:5325] I: rops_handle_POLLOUT_ws: issuing ping on wsi 0x5669090: ws lws-ping-test h2: 0 [2020/03/18 13:13:51:5809] I: lws_ws_client_rx_sm: client 0x5669090 received pong [2020/03/18 13:13:51:5819] I: _lws_validity_confirmed_role: wsi 0x5669090: setting validity timer 3s (hup 0) [2020/03/18 13:13:51:5831] I: Client doing pong callback ...这条链路清晰地展示了 lws 内置的活性校验闭环有效性定时器到期 → 调度校验 → 发出 PING → 收到 PONG → 重置定时器。对语音/实时通信类项目来说这一机制是判断半开连接TCP 已断但应用层无感知的关键手段。批量传输客户端多分片消息与压缩minimal-ws-client-pmd-bulkminimal-ws-client-pmd-bulk 连接localhost:7681上的 minimal-ws-server-pmd-bulk收发一条大型多分片multifragment消息后即退出。运行日志显示LWS_CALLBACK_CLIENT_RECEIVE以 1024 字节分片持续到达最后一帧last 1标记消息结束随后打印Completed OK。使用要点服务器端与客户端必须使用相同选项选项含义-n禁用 permessage-deflate 压缩扩展-c发送可压缩文本而非不可压缩的二进制数据该示例也验证了 permessage-deflate 在批量场景下的作用连接通过压缩扩展建立浏览器访问http://localhost:7681同样能看到服务器推送的批量 WS 数据。如果你需要评估大消息、多分片 压缩对带宽的影响这个示例是现成的基准测试工具。单向接收与发送示例minimal-ws-client-rx / minimal-ws-client-txminimal-ws-client-rx 通过 wss 连接 libwebsockets.org 的 dumb-increment-protocol只做接收把到达的递增数字实时打印RX: 0,RX: 1…以保持代码最小化。官方 README 明确提示收发rx/tx天然支持在同一个协议回调中共存rx 与 tx 只是拆开讲解。minimal-ws-client-tx 则是发布者角色启动两个线程生产消息经本地环形缓冲区ringbuffer加锁保证线程安全汇聚再经由一条钉住的客户端连接发送给 minimal-ws-broker由 broker 把事件分发给所有订阅的浏览器客户端。运行后打开http://localhost:7681即可看到本应用线程产生的订阅消息实时到达。这两个示例合在一起构成了lws 客户端单线程收发 多线程生产/消费的完整编程模型参考接收侧在协议回调中消费数据发送侧把业务线程产生的数据经线程安全缓冲与 lws 事件循环解耦。并发压测客户端连接稳定性测试minimal-ws-client-spamminimal-ws-client-spam 使用 lws-mirror-protocol 连接 libwebsockets.org默认同时保持 10 条并发连接、累计连接 100 次用于压测服务器在大量连接反复建立/断开下的稳定性。命令行参数选项含义-d设置日志详细程度--server指定服务器隐含允许自签名证书--port指定端口-c并发连接数量-l测试上限总计要建立的连接数运行示例——针对本地 TLS 测试服务器进行 20 路并发、200 次连接的压测$ ./lws-minimal-ws-client-spam -c 20 -l 200 --server localhost --port 7681日志中的callback_minimal_spam: established (try 10, est 2, closed 0, err 0)会实时报告第几次尝试、已建立/已关闭/出错连接数是观察连接生命周期与资源回收是否泄漏的直接窗口。在 TEN Framework 中的集成方式作为 TEN Framework 的第三方依赖libwebsockets 通过 third_party/libwebsockets/BUILD.gn 以 GN CMake 混合方式构建其中针对 TEN 的实际使用做了明确裁剪LWS_WITH_MBEDTLSON、LWS_WITH_SSLONTLS 由 mbedTLS 实现构建时通过ten_mbedtls_copy_deps先把 mbedTLS 产物复制到 websockets 构建目录头文件路径通过websockets_headerconfig 暴露给下游LWS_WITH_HTTP2OFF注释说明 lws 的 WS 协议实现目前不支持 HTTP/2且 HTTP/2 要求请求头与请求体分帧发送因此显式关闭避免与 HTTP/1.1 同帧发送的兼容性问题LWS_WITHOUT_TESTAPPSON、LWS_WITHOUT_TEST_SERVERON等生产构建中关闭测试应用避免额外编译负担LWS_ROLE_H1ON、LWS_WITH_SERVERON、LWS_WITH_NETWORKON、LWS_STATIC_PICON启用 H1 角色与服务器能力以 PIC 静态库方式产出。在上层应用中libwebsockets 的 API 被直接用于实现 HTTP 服务器扩展。以 packages/example_extensions/simple_http_server_cpp/src/main.cc 为例它包含libwebsockets.h用struct lws_context承载服务器上下文响应数据写入缓冲区时显式跳过LWS_PRE预留区第 105 行再经lws_add_http_common_headers、lws_finalize_http_header与lws_write(wsi, ..., LWS_WRITE_HTTP_HEADERS)第 110–118 行完成 HTTP 响应。这印证了上文 ws-client 示例中出现的lws_client_connect_via_info、LWS_PRE、回调驱动等核心概念正是 TEN Framework 真实业务代码所直接依赖的同一套 API 面。对应地tests/ten_runtime/smoke/http_server_extension/ 下的集成测试也直接以 libwebsockets 头文件为基础构建说明 lws 已被 TEN 的测试体系覆盖。小结libwebsockets 的 ws-client 示例集覆盖了 WS 客户端开发的全部关键场景重试退避minimal-ws-client、回显与 Autobahn 兼容minimal-ws-client-echo、PING/PONG 活性探测minimal-ws-client-ping、多分片批量传输与压缩minimal-ws-client-pmd-bulk、纯接收minimal-ws-client-rx、多线程发布minimal-ws-client-tx以及并发压测minimal-ws-client-spam。其中以lws_retry_bo_t为核心的连接生命周期管理、以 SUL 调度器驱动的重连机制是最值得在自研实时通信客户端中复用的工程范式而 TEN Framework 已在构建层面完成对 lws 的 TLSmbedTLS、H1 角色与静态库集成为上层 HTTP/WS 扩展提供了可直接依赖的基础设施。赞分享人工智能AI Agent多模态语音AI 应用【免费下载链接】ten-frameworkOpen-source framework for conversational voice AI agents项目地址https://gitcode.com/TEN-framework/ten-framework点击查看免费下载相关推荐为什么你的总战争MOD引用总是出错RPFM依赖管理器Dependencies完整指南为什么你的总战争MOD引用总是出错RPFM依赖管理器Dependencies完整指南 如果你在用 RPFMRusted PackFile Manager一人工智能AI Agent多模态语音AI 应用TEN-framework 依赖库剖析libwebsockets minimal-ws-client-rx 只接收 WebSocket 客户端示例实战与源码解读TEN framework 依赖库剖析libwebsockets minimal ws client rx 只接收 WebSocket 客户端示例实战与源码解人工智能AI Agent多模态语音AI 应用libwebsockets 最小化 MQTT 客户端实战minimal-mqtt-client 单连接与多连接复用示例源码解析libwebsockets 最小化 MQTT 客户端实战minimal mqtt client 单连接与多连接复用示例源码解析 libwebsocketsl人工智能AI Agent多模态语音AI 应用上一篇TKSubmitTransition 开源项目教程下一篇告别繁琐排版vscode-markdown-preview-enhanced的实时预览与自动同步技巧创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表