☰
在 TEN Framework 中用 Node.js 构建 HTTP 服务器扩展:http_server_extension_nodejs 实战指南
2026/9/25 2:19:27 网站建设 项目流程
  • 人工智能
  • AI Agent
  • 多模态
  • 语音
  • AI 应用

【免费下载链接】ten-framework

Open-source framework for conversational voice AI agents

项目地址:https://gitcode.com/TEN-framework/ten-framework
点击查看免费下载

导读

本文围绕 TEN Framework 开源仓库中的官方示例包http_server_extension_nodejs(示例包目录),系统讲解如何在对话式 AI Agent 应用中通过 Node.js 编写一个 HTTP 服务器扩展,将外部 HTTP 请求转换为 TEN 框架内的 Cmd 消息并驱动扩展图中的其他节点。读完本文,你将掌握该扩展的安装方式、manifest.json与图配置的写法、server_port参数配置、以及"HTTP 请求 → Cmd → CmdResult → HTTP 响应"的完整调用链,并了解仓库集成测试如何验证这一链路。

一、扩展概览:这个示例包解决什么问题

该扩展是 TEN Framework 的一个软件包组件(extension package),用 Node.js(TypeScript)编写,核心能力是在 TEN 应用内部启动一个 HTTP 服务器,并把收到的 JSON 请求转译成 TEN 的 Cmd 消息下发到图中其他扩展,再把执行结果回写为 HTTP 响应。

在真实应用场景中,这一模式常用于:外部 Web 前端、移动端或第三方服务通过 HTTP 与 TEN 对话应用交互,例如触发"关闭应用""调用某个扩展能力"等操作,而不必直接接触 TEN 的消息协议。

从仓库元信息看(manifest.json):

  • 包类型为extension,名称为http_server_extension_nodejs,当前版本0.11.73;
  • 标签为nodejs,运行时依赖ten_runtime_nodejs(版本与主框架保持一致);
  • 提供多语言展示名与描述(en-US / zh-CN / zh-TW / ja-JP / ko-KR),并声明了多语言 README 的import_uri。

二、前提条件与安装

2.1 前提条件

  • 一个可用的 TEN Framework 运行环境(含ten_runtime系统包);
  • Node.js 运行时组件ten_runtime_nodejs(版本与扩展一致,即0.11.73),用于加载与执行 TypeScript/JavaScript 扩展;
  • TypeScript 构建工具链(仓库中package.json使用 TypeScript^5.7.2与@types/node ^22.13.5)。

2.2 安装

该扩展作为标准 TEN 软件包,按TEN Framework 软件包安装指南安装即可(如使用tman或构建系统自动拉取依赖)。其依赖关系已在 manifest.json 中声明:

"dependencies": [ { "type": "system", "name": "ten_runtime_nodejs", "version": "0.11.73" } ]

包发布时包含的文件由 BUILD.gn 与manifest.json的package.include共同约束,包括manifest.json、property.json、BUILD.gn、src/**、tsconfig.json、package.json、LICENSE以及docs/**下的多语言文档。

三、扩展的声明与图集成配置

3.1 包声明(manifest.json)

manifest.json是 TEN 包的"身份证",核心字段包括:

字段取值/说明
typeextension,标识这是一个扩展包
namehttp_server_extension_nodejs
version0.11.73,与框架版本对齐
dependencies依赖ten_runtime_nodejs系统包
api空对象,本示例未额外导出 API

3.2 在应用图中挂载扩展

扩展只有被挂载进应用(app)的predefined graph才会随应用启动。以仓库集成测试应用 manifest.json 为例,应用声明依赖:

{ "type": "app", "name": "default_app_nodejs", "version": "0.11.73", "dependencies": [ { "type": "system", "name": "ten_runtime", "version": "0.11.73" }, { "type": "system", "name": "ten_runtime_nodejs", "version": "0.11.73" }, { "type": "extension", "name": "http_server_extension_nodejs", "version": "0.11.73" }, { "type": "extension", "name": "simple_echo_cpp", "version": "0.11.73" } ] }

对应 property.json 中的图配置:

{ "ten": { "predefined_graphs": [ { "name": "default", "auto_start": true, "graph": { "nodes": [ { "type": "extension", "name": "http_server_extension_nodejs", "addon": "http_server_extension_nodejs", "extension_group": "default_extension_group", "property": { "server_port": 8002 } }, { "type": "extension", "name": "simple_echo_cpp", "addon": "simple_echo_cpp", "extension_group": "default_extension_group" } ], "connections": [ { "extension": "http_server_extension_nodejs", "cmd": [ { "name": "test", "dest": [ { "extension": "simple_echo_cpp" } ] } ] } ] } } ] } }

这里的核心点:

  • addon名称http_server_extension_nodejs必须与扩展内@RegisterAddonAsExtension("http_server_extension_nodejs")的注册名一致;
  • 通过节点property中的server_port指定监听端口(此处为 8002),未配置时扩展会回退到默认端口 8001(见下文源码分析);
  • connections定义了http_server_extension_nodejs发出的名为test的 Cmd 路由到simple_echo_cpp,这是"HTTP 请求驱动其他扩展"的关键一步。

四、源码剖析:HTTP 服务器扩展的实现原理

扩展的全部业务逻辑位于 src/index.ts,其结构清晰体现了 TEN Node.js 扩展的标准生命周期。

4.1 类结构与注册机制

import { Addon, RegisterAddonAsExtension, Extension, TenEnv, Cmd, StatusCode, CmdResult, TenError } from "ten-runtime-nodejs"; class HttpServerExtension extends Extension { tenEnv: TenEnv | undefined = undefined; httpServer: http.Server | undefined = undefined; ... } @RegisterAddonAsExtension("http_server_extension_nodejs") class HttpServerExtensionAddon extends Addon { async onCreateInstance(_tenEnv: TenEnv, instanceName: string): Promise<Extension> { return new HttpServerExtension(instanceName); } }
  • 扩展本体继承Extension,通过装饰器@RegisterAddonAsExtension("http_server_extension_nodejs")将 addon 与扩展名绑定;
  • onCreateInstance负责按实例名创建扩展实例,这是 TEN 在图中实例化扩展的入口。

4.2 生命周期回调:配置 → 初始化 → 启动 → 停止 → 销毁

回调职责实现要点
onConfigure读取/下发配置仅记录日志
onInit初始化资源保存tenEnv引用
onStart启动服务读取server_port并创建 HTTP 服务器
onStop优雅停止关闭 HTTP 服务器并等待回调
onDeinit释放资源清空tenEnv引用

onStart是核心实现(src/index.ts):

async onStart(tenEnv: TenEnv): Promise<void> { tenEnv.logInfo("HttpServerExtension onStart"); const hostname = "127.0.0.1"; let [port, err] = await tenEnv.getPropertyNumber("server_port"); if (err != undefined) { port = 8001; // 默认端口 } const server = http.createServer(this.handler.bind(this)); server.listen(port, () => { tenEnv.logInfo("Server running at http://" + hostname + ":" + port + "/"); }); this.httpServer = server; }

注意两点:

  • 端口来源:通过tenEnv.getPropertyNumber("server_port")从图中节点的property读取端口;读取失败时默认8001;
  • 监听地址:固定绑定127.0.0.1,即仅本机可访问,符合示例的安全设定。

4.3 请求处理:HTTP → Cmd → CmdResult → HTTP

handler方法定义了完整的请求处理流程(src/index.ts):

第一步:方法与会话类型校验。仅接受POST且Content-Type: application/json的请求,否则静默返回。

第二步:解析 JSON body,并进行三类分支处理:

  1. JSON 解析失败→ 返回400与Failed to parse JSON;
  2. 请求不含ten字段→ 返回400与No \ten` in JSON data`;
  3. ten.type == "close_app"→ 创建ten:close_app命令并发送给应用(closeAppCmd.setDests([{ appUri: "" }])),随后返回200 {"message": "OK"},实现通过 HTTP 优雅关闭应用;
  4. ten.name存在→ 以该名称创建 Cmd,将原始 body 通过cmd.setPropertyFromJson("", body)注入,并附加method、url两个属性,然后通过this.tenEnv.sendCmd(cmd)下发:
const cmd = Cmd.Create(name); cmd.setPropertyFromJson("", body); cmd.setPropertyString("method", req.method!); cmd.setPropertyString("url", req.url!); this.tenEnv!.sendCmd(cmd).then(([cmdResult, error]) => { if (error) { res.writeHead(500, { "Content-Type": "text/plain" }); res.end("Error: " + error.errorMessage); } else if (cmdResult?.getStatusCode() == StatusCode.OK) { const [detail, err] = cmdResult!.getPropertyToJson("detail"); res.writeHead(200, { "Content-Type": "application/json" }); res.end(detail); } else { res.writeHead(500, { "Content-Type": "text/plain" }); res.end("Internal Server Error"); } });

响应契约约定:下游扩展执行成功后,其 CmdResult 的detail属性会被原样作为 HTTP 响应体返回。因此,若要让 HTTP 调用方拿到业务数据,下游扩展应在结果中写入detail。

第三步:ten结构无效→ 返回400与Invalid ten。

由此可归纳出对外 JSON 请求的两种协议格式:

// 1) 调用图中任意扩展能力 { "ten": { "name": "<cmd名称>", ...任意业务字段 } } // 2) 关闭应用 { "ten": { "type": "close_app" } }

4.4 编译与运行配置

  • package.json:"main": "./build/index.js","type": "module",通过npm run build(即tsc --listEmittedFiles)把 TypeScript 编译到build/;
  • tsconfig.json:target: ES2023、module: NodeNext、开启experimentalDecorators与emitDecoratorMetadata(装饰器语法必需)、strict严格模式,输出到build目录并生成sourceMap。

五、集成测试:如何验证这条调用链

仓库在 tests/ten_runtime/integration/nodejs/http_server_nodejs 提供了完整的集成测试,从测试角度印证了上述行为:

  • 测试应用http_server_nodejs_app将 HTTP 扩展与simple_echo_cpp连成图,并把server_port设为8002;
  • test_case.py 的核心逻辑:
    1. 组装并构建应用包(prepare_and_build_app);
    2. 编译 TypeScript 扩展(build_nodejs_extensions);
    3. 启动应用(bin/start),并轮询等待应用在 8002 端口就绪;
    4. 向http://127.0.0.1:8002/发送请求:
def http_request(): return http.post( "http://127.0.0.1:8002/", { "ten": { "name": "test", }, }, )
  1. 断言响应码不等于 500,验证"HTTP POST → Cmdtest→simple_echo_cpp→ CmdResult → HTTP 响应"整条链路可用;
  2. 结束后通过stop_app优雅关闭应用并断言退出码为 0。

该测试同时验证了跨语言协作:HTTP 扩展是 Node.js,而目标扩展simple_echo_cpp是 C++,说明 HTTP 网关式扩展可以无缝驱动任意语言实现的扩展节点。

六、快速上手:从零集成到你的 TEN 应用

  1. 准备应用:在应用manifest.json的dependencies中加入http_server_extension_nodejs与ten_runtime_nodejs(版本对齐);
  2. 配置图:在应用property.json的predefined_graphs中挂载该扩展节点,设置server_port(例如 8002),并通过connections把你要暴露的 Cmd 名称路由到目标扩展;
  3. 构建扩展:进入扩展目录执行npm install与npm run build(tsc编译到build/);
  4. 启动应用:启动 TEN 应用后,扩展会在http://127.0.0.1:<server_port>/提供 HTTP 服务;
  5. 发起请求:
curl -X POST http://127.0.0.1:8002/ \ -H "Content-Type: application/json" \ -d '{"ten":{"name":"test"}}'

七、常见问题与注意事项

  • 端口冲突/未生效:确认图中节点的property.server_port已正确配置;扩展读取失败时默认回退 8001,可能与其他服务冲突;
  • 请求被静默忽略:仅POST+application/json会被处理,其他方法与 Content-Type 不会进入处理分支;
  • 400 响应排查:检查请求体是否含ten字段、JSON 是否合法、ten内是否有name或type;
  • 500 响应排查:sendCmd返回error,或目标扩展返回的CmdResult状态码不是StatusCode.OK,此时可检查图中 Cmd 名称的路由(connections)是否配置正确,以及下游扩展是否在结果中写入detail;
  • 安全边界:示例固定监听127.0.0.1,仅本机可访问;生产环境如需对外暴露,应在网络层做好鉴权与安全策略。

八、许可证

本扩展包隶属于 TEN Framework 项目,遵循 Apache License 2.0(见 LICENSE),与框架本身的开源许可保持一致。

  • 人工智能
  • AI Agent
  • 多模态
  • 语音
  • AI 应用

【免费下载链接】ten-framework

Open-source framework for conversational voice AI agents

项目地址:https://gitcode.com/TEN-framework/ten-framework
点击查看免费下载

相关推荐

上一篇:【亲测免费】 sse.js 使用与安装指南
下一篇:RCX安全最佳实践:如何安全地管理和传输云存储文件

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询