45、【Agent】【OpenCode】本地代理分析(请求&接收回调)

【声明】本博客所有内容均为个人业余时间创作,所述技术案例均来自公开开源项目(如Github,Apache基金会),不涉及任何企业机密或未公开技术,如有侵权请联系删除

背景

上篇 blog
【Agent】【OpenCode】本地代理分析(效果呈现)

分析了其中的接收回调函数,提到了入参 proxyRes 不是用户自定义的局部变量,而是 Node.js 在触发接收回调时,动态创建的参数,每次收到一个响应,系统都会新建一个 proxyRes 对象传进来,另外分析了内存安全的问题,提到客户端响应对象 res 的生命周期由 Node.js 管理,一旦 proxyRes.pipe(res) 完成,或者当 HTTP 连接关闭时,res 会被自动清理,不会出现内存泄漏,最后总结了下本地代理的关键点,正是这种非阻塞式,事件驱动的模型,可以让 Node.s 能够高效处理成千上万的并发 AI 请求,然后改掉 opencode.json 中的 api 为本地代理的 URL,启用本地代理,再打开 OpenCode 客户端,发送请求,可以看到代理的转发过程,下面继续分析

OpenCode

上篇 blog 已经演示了本地代理的启动和运行,下面最后再解释下 http.createServer 的工作机制,以及它和 https.request 接收回调之间的关系


首先,http.createServer 创建的是一个请求处理函数

javascript 复制代码
const server = http.createServer((req, res) => {
  // 请求处理函数(Request Handler)
});

其中

  • 返回值 :一个 http.Server 实例(server.listen 可监听端口)
  • 参数 (req, res) => {...} :本质也是个回调函数(就像 https.request 创建的接收回调一样),Node.js 称之为请求监听器(request listener)

每当有客户端(OpenCode)发起 HTTP 请求到本地代理时,Node.js 就会自动调用这个函数,简单来说,createServer 创建的是当有用户访问时,要做什么的逻辑

然后是触发条件,只有当外部客户端,比如 OpenCode,浏览器,curl 命令向本地代理的 Node.js 服务器发起 HTTP 请求时,才会触发 ,举个例子

  • 运行服务器:server.listen(2048)
  • OpenCode 客户端发送请求:POST http://localhost:2048/v1/chat/completions
  • Node.js 收到 TCP 连接,解析 HTTP 请求
  • 自动调用 createServer 定义的请求处理函数 (req, res) => {...},其中 req 为 OpenCode 发来的请求对象(包含 method,url,headers,body 等),res 为要写回给 OpenCode 的响应对象

关键点:(req, res) => {...} 只被入站请求触发,链路如下

然后是目标服务器 DashScope 的响应,接收 DashScope 的响应和 createServer 就没关系了,也不会触发 (req, res) => {...},而是触发 https.request 定义的接收回调函数 (proxyRes) => {...},所以总结下这两个事件如下

  • OpenCode 客户端:负责发送请求,处理函数为 http.createServer 创建的 (req, res) => {...},由 Node.js 调用,触发时机为收到外部 HTTP 请求
  • DashScope 目标服务器:负责返回响应,处理函数为 https.request 创建的 (proxyRes) => {...},同样由 Node.js 调用,触发时机为收到上游服务器的 HTTPS 响应

其数据流向如下

可以看到,这两个回调是独立的,一个是主动请求后结果处理,本地代理去找目标服务器,另一个则是被动接收,目标服务器来找本地代理

另外,每个请求都有独立的作用域和生命周期,即使同时有 100 个 OpenCode 请求,每个请求都会有自己的 (req, res) 和自己的 https.request,Node.js 通过闭包和事件循环确保数据彼此之间互不串扰

javascript 复制代码
http.createServer((req_from_opencode, res_to_opencode) => {
  // 这个作用域只属于 OpenCode 的这一次请求

  const proxyReq = https.request(dashscope_options, (res_from_dashscope) => {
    // 这个回调属于此次向 DashScope 发起的请求后的响应
    // 但它能访问外层的 res_to_opencode(闭包!)
    res_to_opencode.writeHead(res_from_dashscope.statusCode, ...);
    res_from_dashscope.pipe(res_to_opencode);
  });

  proxyReq.end(body);
});

OK,本篇先到这里,如有疑问,欢迎评论区留言讨论,祝各位功力大涨,技术更上一层楼!!!更多内容见下篇 blog
【Agent】【OpenCode】本地代理增强(日志记录)

相关推荐
唐某人丶4 小时前
模型越来越强,我们还需要 Agent 工程吗?—— 从价值重估到 Harness 实践
前端·agent·ai编程
程序员cxuan5 小时前
为每个任务配一套 harness:Claude Code 里的动态工作流
人工智能
程序员cxuan5 小时前
Claude Fable 5 来了
人工智能·后端·程序员
云边云科技_云网融合5 小时前
云边云科技亮相 2026 WOD 制造业数智化博览会 云网融合赋能制造焕新
人工智能·科技·安全·制造
Σίσυφος19005 小时前
激光三角 光平面标定-多高度误差分析
人工智能·计算机视觉·平面
JS菌5 小时前
手写一个 AI Agent 全栈项目:从沙箱执行到子智能体的完整实现
前端·人工智能·后端
lqqjuly5 小时前
前沿算法深度解析(二)
人工智能·算法·机器学习
Bode_20025 小时前
基于大数据分析的全生命周期质量追溯质量评估体系落地方案
大数据·人工智能
分布式存储与RustFS5 小时前
RustFS S3 Table 开源后,我重新梳理了一下 Iceberg 数据湖的选型思路
人工智能·开源·minio·dpu·rustfs·ai存储·s3 table
DevOpenClub6 小时前
用 Agent 搭建网页内容采集与结构化处理流水线
人工智能