構(gòu)體的離線轉(zhuǎn)換工具)
人工智能AI Agent多模態(tài)語音AI 應(yīng)用【免費(fèi)下載鏈接】ten-frameworkOpen-source framework for conversational voice AI agents項(xiàng)目地址https://gitcode.com/TEN-framework/ten-framework點(diǎn)擊查看免費(fèi)下載本篇文章講解 libwebsocketslwsSecure Streams 體系中一個(gè)特殊而實(shí)用的工具lws-minimal-secure-streams-policy2c。它的作用是把一份以 JSON 書寫的 Secure Streams 策略從標(biāo)準(zhǔn)輸入讀入并解析然后在標(biāo)準(zhǔn)輸出上生成一份可直接參與編譯的 C 結(jié)構(gòu)體源碼。這樣在那些內(nèi)存受限、無法在運(yùn)行時(shí)解析動(dòng)態(tài) JSON 策略的嵌入式平臺(tái)上依然可以繼續(xù)用 JSON 維護(hù)和演進(jìn)策略再借助本工具把策略燒錄成固件里的靜態(tài)數(shù)據(jù)。讀完本文你將掌握這個(gè)轉(zhuǎn)換工具的使用方式、生成產(chǎn)物的結(jié)構(gòu)、以及它如何與LWS_WITH_SECURE_STREAMS_STATIC_POLICY_ONLY靜態(tài)策略模式配合實(shí)現(xiàn)一份 JSON多端部署的落地路徑。這個(gè)工具解決什么問題Secure Streams 是 lws 提供的網(wǎng)絡(luò) API它的設(shè)計(jì)把載荷與元數(shù)據(jù)嚴(yán)格分離連接的目標(biāo)地址、TLS 信任鏈、甚至所使用的協(xié)議都被收納進(jìn)一份策略數(shù)據(jù)庫(kù)policy database應(yīng)用代碼只負(fù)責(zé)收發(fā)載荷與接收連接狀態(tài)回調(diào)。策略通常以 JSON 形式在lws_context創(chuàng)建時(shí)傳入甚至可以從遠(yuǎn)端更新。但并非所有平臺(tái)都適合動(dòng)態(tài)解析 JSON。對(duì)于 Flash/RAM 緊張的嵌入式目標(biāo)運(yùn)行時(shí)解析 JSON 策略既不劃算也有風(fēng)險(xiǎn)。policy2c 正是為這一場(chǎng)景準(zhǔn)備的你仍然用 JSON 維護(hù)和編寫策略便于閱讀、審查、版本管理在 PC/構(gòu)建機(jī)上運(yùn)行本工具把 JSON 一次性地轉(zhuǎn)換為可編譯的 C 結(jié)構(gòu)體生成的 C 代碼直接包含進(jìn)固件目標(biāo)設(shè)備無需 JSON 解析器即可使用 Secure Streams。從源碼注釋可以看到它定位的描述Its useful if your platform is too space-constrained for a JSON policy and needs to build a static policy in C via LWS_WITH_SECURE_STREAMS_STATIC_POLICY_ONLY... this way you can still create and maintain the JSON policy but implement it directly as C structs in your code.見 minimal-secure-streams.c 文件頭注釋。依賴與構(gòu)建編譯前提policy2c 自身需要在支持完整協(xié)議角色的 lws 構(gòu)建上編譯因?yàn)樗仨毮芙馕鋈我獠呗詢?nèi)容——無論是 HTTP/1、HTTP/2、WebSocket 還是 MQTT 的 streamtype。工具文檔明確指出它依賴LWS_ROLE_H1、LWS_ROLE_H2、LWS_ROLE_WS與LWS_ROLE_MQTT四個(gè)構(gòu)建選項(xiàng)。這一依賴也反映在它的 CMakeLists.txt 中require_lws_config(LWS_ROLE_H1 1 requirements) require_lws_config(LWS_ROLE_H2 1 requirements) require_lws_config(LWS_ROLE_MQTT 1 requirements) require_lws_config(LWS_WITHOUT_CLIENT 0 requirements) require_lws_config(LWS_WITH_SECURE_STREAMS 1 requirements) require_lws_config(LWS_WITH_SECURE_STREAMS_STATIC_POLICY_ONLY 0 requirements)其中最后一行很有意思policy2c 作為生成器工具運(yùn)行在 PC 上因此它自身不需要以靜態(tài)策略模式構(gòu)建相反靜態(tài)策略模式LWS_WITH_SECURE_STREAMS_STATIC_POLICY_ONLY1是它生成物所服務(wù)的下游目標(biāo)形態(tài)。構(gòu)建命令與絕大多數(shù) lws minimal example 相同在示例目錄中直接執(zhí)行$ cmake . make構(gòu)建產(chǎn)物是可執(zhí)行文件lws-minimal-secure-streams-policy2c。使用方式命令行參數(shù)命令行選項(xiàng)含義-d loglevel調(diào)試輸出詳細(xì)程度十進(jìn)制例如-d15基本用法工具從stdin讀取 JSON 策略向stdout輸出等價(jià)的 C 結(jié)構(gòu)體源碼$ cat mypolicy.json | lws-minimal-secure-streams-policy2c (on stdout) static const uint32_t _rbo_bo_0[] { 1000, 2000, 3000, 5000, 10000, }; static const lws_retry_bo_t _rbo_0 { .retry_ms_table _rbo_bo_0, .retry_ms_table_count 5, .conceal_count 5, .secs_since_valid_ping 30, .secs_since_valid_hangup 35, .jitter_percent 20, }; static const uint8_t _ss_der_amazon_root_ca_1[] { /* 0x 0 */ 0x30, 0x82, 0x03, 0x41, 0x30, 0x82, 0x02, 0x29, /* 0x 8 */ 0xA0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x13, 0x06, /* 0x 10 */ 0x6C, 0x9F, 0xCF, 0x99, 0xBF, 0x8C, 0x0A, 0x39, /* 0x 18 */ 0xE2, 0xF0, 0x78, 0x8A, 0x43, 0xE6, 0x96, 0x36, /* 0x 20 */ 0x5B, 0xCA, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, ...重定向即可保存$ cat mypolicy.json | lws-minimal-secure-streams-policy2c static-policy.h轉(zhuǎn)換過程與源碼級(jí)原理整體流程從 minimal-secure-streams.c 的main()可以看出轉(zhuǎn)換的大致步驟創(chuàng)建lws_contextCONTEXT_PORT_NO_LISTEN即不監(jiān)聽任何端口調(diào)用lws_ss_policy_parse_begin(context, 0)開始一次策略解析會(huì)話循環(huán)從 stdinread()數(shù)據(jù)塊逐塊交給lws_ss_policy_parse()做增量解析若返回錯(cuò)誤且不是LEJP_CONTINUE表示數(shù)據(jù)尚未完整需要繼續(xù)喂入則視為解析失敗并退出解析完成后通過lws_ss_policy_get(context)取得內(nèi)存中的策略對(duì)象鏈表逐類遍歷并輸出對(duì)應(yīng)的 C 結(jié)構(gòu)體。過程中還會(huì)在輸出頭部把原始 JSON 原樣回顯并用#if 0 ... #endif包起來同時(shí)打印 Original JSON size: xxx 提示原始策略的體積結(jié)尾會(huì)打印一段估計(jì)的 C 側(cè)內(nèi)存占用例如/* estimated footprint 10720 (when sizeof void * 8) */這個(gè)估計(jì)值由工具內(nèi)部累加各結(jié)構(gòu)體sizeof與證書 DER 長(zhǎng)度得到方便評(píng)估靜態(tài)策略的最終成本。標(biāo)識(shí)符清洗purify_csymbolJSON 里的名稱streamtype、metadata 名、證書名、auth 名、trust store 名等要變成合法的 C 標(biāo)識(shí)符。工具用purify_csymbol()把任何既不是字母也不是數(shù)字的字符替換成下劃線_例如api.amazon.com這類名字在生成的結(jié)構(gòu)體命名中會(huì)以_ss_ts_api_amazon_com的形式出現(xiàn)。這是從源碼中可以明確確認(rèn)的實(shí)現(xiàn)事實(shí)。去重機(jī)制轉(zhuǎn)換器在遍歷策略時(shí)維護(hù)了三個(gè)已見過映射見 minimal-secure-streams.c 中的rbomap、trustmap、certmapretry/backoff 對(duì)象多個(gè) streamtype 往往共享同一個(gè)retry: default重試方案工具只輸出一份_rbo_NN 為遞增序號(hào)trust store同一信任庫(kù)被多個(gè) streamtype 引用時(shí)只生成一份_ss_ts_namex.509 證書證書按名稱去重DER 字節(jié)只輸出一份_ss_der_name數(shù)組并伴隨一個(gè)_ss_x509_name包裝結(jié)構(gòu)。其余 streamtype 之間通過next指針串成鏈表所有指針在輸出時(shí)都指向已生成的static const對(duì)象因此最終產(chǎn)物是一批相互引用的編譯期常量天然適合放進(jìn)只讀存儲(chǔ)器。各類生成物的結(jié)構(gòu)從工具源碼與倉(cāng)庫(kù)內(nèi)已生成的 static-policy.h 可以總結(jié)出產(chǎn)物涵蓋的類型生成物對(duì)應(yīng) JSON 概念說明_md_streamtype_namestreamtype 的metadata條目lws_ss_metadata_t數(shù)組含 name、可選默認(rèn)值、長(zhǎng)度等_rbo_bo_n/_rbo_nretry[].backoff / conceal / jitterpc等uint32_t延時(shí)表 lws_retry_bo_t重試/退避結(jié)構(gòu)_ss_der_cert/_ss_x509_certcerts中的 base64 DER 證書uint8_t字節(jié)數(shù)組 lws_ss_x509_t包裝_ss_ts_storetrust_storeslws_ss_trust_store_t內(nèi)含ssx509[]證書指針數(shù)組streamtype_http_respmaphttp_resp_mapHTTP 響應(yīng)碼到 SS 狀態(tài)的映射表_ssau_nameauth條目lws_ss_auth_tname/type/streamtype/blob_index_ssp_streamtypes中的每個(gè) streamtypelws_ss_policy_t策略結(jié)構(gòu)含協(xié)議聯(lián)合體u.http/u.mqtt其中l(wèi)ws_ss_policy_t的u聯(lián)合體按協(xié)議分支輸出H1 / H2 / WS輸出.http.method/.url/.multipart_name/.auth_preamble/.respmap/.blob_header/.resp_expect/.fail_redirect等若協(xié)議是 WS還會(huì)嵌套輸出.u.ws.subprotocol/.binaryMQTT輸出.mqtt.topic/.subscribe/.will_*/.birth_*/.keep_alive/.qos/.clean_start/.aws_iot/.retain等其余協(xié)議索引會(huì)觸發(fā)錯(cuò)誤退出unknown ss protocol index這提示工具只支持這四類協(xié)議角色的策略內(nèi)容。streamtype 結(jié)構(gòu)最后還會(huì)輸出timeout_ms、flags、priority、port、metadata_count、protocol、client_cert、trust以及retry_bo指針引用如果 lws 構(gòu)建時(shí)啟用了LWS_WITH_SECURE_STREAMS_AUTH_SIGV4還會(huì)額外輸出aws_region/aws_service字段見源碼中該宏條件編譯塊。輸出鏈表的頭結(jié)點(diǎn)在最后以宏形式標(biāo)記出來#define _ss_static_policy_entry _ssp_api_amazon_com_auth這個(gè)宏正是靜態(tài)策略模式下應(yīng)用通過info.pss_policies _ss_static_policy_entry;掛載給lws_context的入口。產(chǎn)物如何被下游使用static policy 模式配套示例 minimal-secure-streams-staticpolicy倉(cāng)庫(kù)里有一個(gè)與 policy2c 直接配套的示例 minimal-secure-streams-staticpolicy它演示了用 policy2c 生成的靜態(tài)策略跑真實(shí) HTTP 客戶端的完整鏈路應(yīng)用訪問https://warmcat.com/并讀取其 index.html。該目錄下有三個(gè)關(guān)鍵文件static-policy.json原始 JSON 策略內(nèi)含 retry 方案、多張 CA 證書、trust store、以及mintest、avs_*、mqtt_test*、captive_portal_detect等一批 streamtypestatic-policy.h由 policy2c 從該 JSON 生成的 C 頭文件約 1500 行頭部#if 0塊中嵌著原始 JSON 與 Original JSON size: 15493文件末尾即為_ssp_*策略鏈表與#define _ss_static_policy_entry _ssp_api_amazon_com_authminimal-secure-streams.c應(yīng)用本體直接#include static-policy.h。在應(yīng)用側(cè)靜態(tài)策略通過lws_context_creation_info的pss_policies字段掛載info.pss_policies _ss_static_policy_entry; info.options LWS_SERVER_OPTION_EXPLICIT_VHOSTS | LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT;然后照常創(chuàng)建mintest類型的 Secure Streamssi.streamtype mintest; lws_ss_create(context, 0, ssi, NULL, NULL, NULL, NULL);在LWSSSCS_CREATING狀態(tài)里通過lws_ss_set_metadata()設(shè)置uptag、ctype等元數(shù)據(jù)再lws_ss_client_connect()發(fā)起連接最后在 rx 回調(diào)中收到頁(yè)面載荷。其 CMakeLists.txt 也印證了靜態(tài)策略模式是構(gòu)建前提require_lws_config(LWS_ROLE_H1 1 requirements) require_lws_config(LWS_WITHOUT_CLIENT 0 requirements) require_lws_config(LWS_WITH_SECURE_STREAMS 1 requirements) require_lws_config(LWS_WITH_SECURE_STREAMS_STATIC_POLICY_ONLY 1 requirements)注意這個(gè)下游示例只需要LWS_ROLE_H1而生成它的 policy2c 卻要求四種角色——這正是生成端全能力、運(yùn)行端按需裁剪的典型分工。運(yùn)行輸出示例README 中記錄了該靜態(tài)策略客戶端的典型運(yùn)行日志$ ./lws-minimal-secure-streams-staticpolicy [2020/03/26 15:49:12:6640] U: LWS secure streams static policy test client [-dverb] [2020/03/26 15:49:12:7067] N: lws_create_context: using ss proxy bind (null), port 0, ads (null) [2020/03/26 15:49:12:7567] N: lws_tls_client_create_vhost_context: using mem client CA cert 914 ... [2020/03/26 15:49:13:9625] N: ss_api_amazon_auth_rx: acquired 588-byte api.amazon.com auth token, exp 3600s [2020/03/26 15:49:13:9747] U: myss_state: LWSSSCS_CREATING, ord 0x0 [2020/03/26 15:49:13:9774] U: myss_state: LWSSSCS_CONNECTING, ord 0x0 [2020/03/26 15:49:14:1897] U: myss_state: LWSSSCS_CONNECTED, ord 0x0 [2020/03/26 15:49:14:1926] U: myss_rx: len 1520, flags: 1 ... [2020/03/26 15:49:14:2136] U: myss_rx: len 0, flags: 2 [2020/03/26 15:49:14:2137] U: myss_state: LWSSSCS_QOS_ACK_REMOTE, ord 0x0 [2020/03/26 15:49:14:2170] U: myss_state: LWSSSCS_DISCONNECTED, ord 0x0 [2020/03/26 15:49:14:2192] U: myss_state: LWSSSCS_DESTROYING, ord 0x0 [2020/03/26 15:49:14:2282] U: Completed: OK可以看到日志中 TLS vhost 使用的 CA 證書來自mem內(nèi)存中的靜態(tài) DER 數(shù)組即 policy2c 生成物且整個(gè)流程經(jīng)歷了CREATING → CONNECTING → CONNECTED → QOS_ACK_REMOTE → DISCONNECTED → DESTROYING的完整 Secure Streams 狀態(tài)機(jī)。構(gòu)建模式說明LWS_WITH_SECURE_STREAMS_STATIC_POLICY_ONLY模式下 lws 不會(huì)構(gòu)建 JSON 策略解析器若項(xiàng)目其他部分也用不到 LEJP 解析器還可以順帶關(guān)閉 LEJP 選項(xiàng)再省下約 2KB 空間這一數(shù)量說明來自 libwebsockets 自帶的 Secure Streams 總覽文檔 lib/secure-streams/README.md 中 Using static policies 一節(jié)。這正是 policy2c 存在意義的量化注腳。JSON 策略關(guān)鍵字段速覽由于 policy2c 的輸入即 Secure Streams JSON 策略掌握輸入格式才能用好該工具。以下字段來自 lib/secure-streams/README.md 的 JSON Policy Database 一節(jié)與倉(cāng)庫(kù)內(nèi) static-policy.json 相互印證字段作用release/product/schema-version策略版本、適用產(chǎn)品、解析器最低版本要求retry[]重試/退避方案集合內(nèi)部含backoff逐次毫秒延時(shí)數(shù)組、conceal向上層隱藏的失敗次數(shù)65535 表示永不放棄、jitterpc延時(shí)隨機(jī)抖動(dòng)百分比防重試風(fēng)暴等certs校驗(yàn)所需的 CA 證書格式為 base64 DER即 PEM 首尾行之間的內(nèi)容trust_stores由certs組成的命名證書鏈每個(gè)條目會(huì)創(chuàng)建對(duì)應(yīng)命名的 vhost TLS 上下文auth認(rèn)證方案映射name/type/streamtype/blob如 sigv4s各 streamtype 的策略定義數(shù)組是轉(zhuǎn)換的主體streamtype 常用成員包括endpoint支持${metadata}運(yùn)行時(shí)替換前綴表示 Unix Domain Socket、port、protocolh1/h2/ws/mqtt/raw、tls、tls_trust_store、retry、opportunistic、nailed_up、timeout_ms、metadata[]、HTTP 類http_method/http_url/http_expect/http_fail_redirect/http_auth_header/http_auth_preamble/http_resp_map/http_multipart_*、WS 類ws_subprotocol/ws_binary、MQTT 類mqtt_topic/mqtt_subscribe/mqtt_qos/mqtt_keep_alive/mqtt_will_*/mqtt_clean_start等。轉(zhuǎn)換器對(duì)這些字段的 C 輸出分支與上述列表一一對(duì)應(yīng)。最佳實(shí)踐與注意事項(xiàng)工具跑在構(gòu)建機(jī)不在目標(biāo)機(jī)policy2c 需要在帶全角色H1/H2/WS/MQTT的 lws 構(gòu)建下編譯運(yùn)行其輸出才參與固件編譯。目標(biāo)設(shè)備側(cè)則按需啟用LWS_WITH_SECURE_STREAMS_STATIC_POLICY_ONLY只編譯必需的協(xié)議角色。一次轉(zhuǎn)換多處復(fù)用policy2c 已做過去重優(yōu)化共享的 retry 方案、trust store、證書只會(huì)生成一份常量多個(gè) streamtype 通過指針引用降低最終體積。JSON 仍是唯一事實(shí)來源把static-policy.json納入版本管理改策略時(shí)只改 JSON、重新運(yùn)行轉(zhuǎn)換避免手改 C 產(chǎn)物——這既保持了 JSON 的可讀可審也保證生成物與策略嚴(yán)格同步。關(guān)注體積預(yù)算工具會(huì)回顯原始 JSON 字節(jié)數(shù)并在結(jié)尾打印估計(jì) footprint如estimated footprint 10720可用于靜態(tài)策略的 ROM 成本評(píng)估。協(xié)議角色對(duì)齊輸入策略中出現(xiàn)ws或mqttstreamtype 時(shí)policy2c 的構(gòu)建必須具備對(duì)應(yīng)角色否則解析會(huì)失敗源碼在解析錯(cuò)誤時(shí)輸出lws has WITH_ROLEs for whats in the JSON?的提示。相關(guān)資源工具本體minimal-secure-streams.c 與 CMakeLists.txt靜態(tài)策略配套示例minimal-secure-streams-staticpolicy其 static-policy.h 是 policy2c 的真實(shí)產(chǎn)出樣例static-policy.json 是對(duì)應(yīng)輸入Secure Streams 總覽與 JSON 策略字段詳解lib/secure-streams/README.md相關(guān) CMake 配置項(xiàng)在 lib/secure-streams/CMakeLists.txt 與 CMakeLists.txt 中定義贊分享人工智能AI Agent多模態(tài)語音AI 應(yīng)用【免費(fèi)下載鏈接】ten-frameworkOpen-source framework for conversational voice AI agents項(xiàng)目地址https://gitcode.com/TEN-framework/ten-framework點(diǎn)擊查看免費(fèi)下載相關(guān)推薦libwebsockets Secure Streams 靜態(tài)策略示例實(shí)戰(zhàn)從 JSON 策略到 C 代碼的完整鏈路libwebsockets Secure Streams 靜態(tài)策略示例實(shí)戰(zhàn)從 JSON 策略到 C 代碼的完整鏈路 本篇指南圍繞 libwebsockets人工智能AI Agent多模態(tài)語音AI 應(yīng)用Xinference 部署 llama-3-instruct 完全指南模型規(guī)格、量化選項(xiàng)與多引擎啟動(dòng)命令詳解Xinference 部署 llama 3 instruct 完全指南模型規(guī)格、量化選項(xiàng)與多引擎啟動(dòng)命令詳解 本文基于 Xinference 內(nèi)置模型文檔 l人工智能AI Agent多模態(tài)語音AI 應(yīng)用倉(cāng)頡宏原理實(shí)戰(zhàn)hystrix-cj的ProtectedResrouce如何用Token插碼實(shí)現(xiàn)零侵入熔斷倉(cāng)頡宏原理實(shí)戰(zhàn)hystrix cj的ProtectedResrouce如何用Token插碼實(shí)現(xiàn)零侵入熔斷 hystrix cj 是一個(gè)面向倉(cāng)頡語言的熔斷降級(jí)人工智能AI Agent多模態(tài)語音AI 應(yīng)用上一篇UPNG.js 開源項(xiàng)目教程下一篇Moveable 開源項(xiàng)目教程創(chuàng)作聲明:本文部分內(nèi)容由AI輔助生成(AIGC),僅供參考