arduino-cli gRPC 客户端实战:用 client_example 打通 daemon 服务与代理链路
开发工具嵌入式【免费下载链接】arduino-cliArduino command line tool项目地址https://gitcode.com/gh_mirrors/ar/arduino-cli点击查看免费下载client_example是 arduino-cli 仓库中一个专门模拟 gRPC 消费者的示例客户端其完整源码位于 rpc/internal/client_example含main.go、squid.conf与一个测试用 sketch。本文以 rpc/internal/client_example/README.md 为骨架逐步讲解如何启动arduino-cli daemon、运行客户端走通从版本查询到平台/库管理的完整调用链并通过 Docker Squid 代理验证 arduino-cli 的network.proxy配置是否真正生效。读完本文你将能够独立搭建一套gRPC 服务端 外部客户端 本地代理的联调环境并理解 arduino-cli 的核心 RPC 接口形态。一、client_example 是什么按照 README 的定位这是一个模拟 gRPC 消费者的客户端程序。arduino-cli 的 gRPC 接口文档相对零散官方暂时用它来记录与 gRPC 接口的交互方式——也就是说main.go中每一次 RPC 调用都是对 daemon 模式下 arduino-cli 对外 API 的活文档。整个目录结构如下rpc/internal/client_example/main.go客户端主程序演示数十个 RPC 方法的标准调用方式rpc/internal/client_example/squid.conf用于代理验证实验的 Squid 配置文件rpc/internal/client_example/hello/hello.ino一个仅含空setup()/loop()的最小测试 sketch供LoadSketch、Compile等接口使用。服务端的 RPC 方法清单在 rpc/cc/arduino/cli/commands/v1/commands.proto 中统一定义Create、Init、UpdateIndex、PlatformInstall、Compile、Upload、LibraryInstall、Monitor、Debug、SettingsGetValue/SettingsSetValue等全部通过ArduinoCoreService服务暴露。二、快速开始daemon 与客户端的组合运行README 给出的使用方式非常简洁只有两步arduino-cli daemon client_example第一步启动 arduino-cli 的 gRPC 服务端第二步运行示例客户端二者默认在localhost:50051上建立连接。从源码看客户端连接逻辑在 rpc/internal/client_example/main.go#L44-L50conn, err : grpc.NewClient(localhost:50051, grpc.WithTransportCredentials(insecure.NewCredentials())) if err ! nil { log.Fatal(error connecting to arduino-cli rpc server, you can start it by running arduino-cli daemon) }需要说明两点前提连接为明文传输示例使用grpc.WithTransportCredentials(insecure.NewCredentials())不启用 TLS因此只适合本机联调默认端口来自配置50051是daemon.port的默认值定义在 internal/cli/configuration/defaults.godaemon 命令实际监听地址在 internal/cli/daemon/daemon.go 中被固定为127.0.0.1。daemon 命令的可调参数结合 internal/cli/daemon/daemon.goarduino-cli daemon支持以下参数参数默认值说明--port配置项daemon.port默认 50051daemon 监听的 TCP 端口传0时由操作系统随机分配并回显实际端口--daemonizefalse为true时父进程结束后 daemon 不随之退出--debugfalse启用 gRPC 调用的调试日志--debug-file空将调试日志追加写入指定文件必须与--debug同时使用--debug-filter[]只显示指定的 gRPC 调用--max-grpc-recv-message-size16 MiBdaemon 可接收的最大消息字节数必须 1024服务端启动后会打印监听地址与端口daemonResult随后阻塞在s.Serve(lis)上等待客户端连接。三、客户端完整调用链逐段拆解main.go的main()函数把一次典型的 Arduino 工作流串成了顺序调用。理解这条调用链就等于掌握了 arduino-cli gRPC API 的使用顺序其中几个关键阶段尤其值得注意。3.1 无状态接口先行Version 与 LoadSketch客户端最先调用Version与LoadSketch注释明确说明它们不需要任何 setup 或 init 流程rpc/internal/client_example/main.go#L67-L72。callVersion直接请求服务端版本号callLoadSketch则读取hello目录的 sketch 信息返回主文件、位置、其他 sketch 文件与附加文件列表。3.2 用 Settings 接口隔离测试环境为不污染现有 arduino-cli 安装客户端通过os.MkdirTemp创建临时目录作为数据目录再通过SettingsSetValue写入三个关键路径rpc/internal/client_example/main.go#L74-L77callSetValue(client, directories.data, dataDir) callSetValue(client, directories.downloads, path.Join(dataDir, staging)) callSetValue(client, directories.user, path.Join(dataDir, sketchbook))这里体现出SettingsSetValueRequest的设计要点EncodedValue是JSON 编码的字符串所以路径要加引号、数组要用方括号。随后示例演示了修改-保存-回读-再保存的完整流程callConfigurationSave以 JSON 格式输出当前全部配置对应 proto 中的ConfigurationSaveRequestsettings_format允许json或yaml见 rpc/cc/arduino/cli/commands/v1/settings.proto一次SetValue修改daemon.port为422、board_manager.additional_urls为数组[ https://example.com ]再次保存用SettingsGetValue回读daemon.port与directories.data将daemon.port置空后再次保存。3.3 实例生命周期Create → Init → 后续操作Create返回一个Instance此后所有需要上下文的 RPC 都要携带这个实例 ID。Init是服务端流式接口客户端必须循环Recv()直到io.EOF期间解析两种消息rpc/internal/client_example/main.go#L301-L333GetDownloadProgress()索引文件下载进度GetTaskProgress()初始化任务阶段。3.4 平台管理更新索引、搜索、安装、升级、卸载UpdateIndex同样是流式接口客户端循环消费下载进度直到 EOF。值得注意的细节是索引更新后不会被隐式检测必须再次调用Init才能加载新索引——示例在UpdateIndex之后显式追加了一次Initrpc/internal/client_example/main.go#L116-L119。平台管理调用的完整序列为PlatformSearch(samd)搜索平台打印id与latest versionPlatformInstall(arduino:samd1.6.19)安装指定版本消费下载进度与任务进度PlatformUpgrade(arduino:samd)升级到最新版BoardDetails(arduino:samd:mkr1000)查询板卡详情工具依赖、配置选项BoardSearch()全量搜索板卡最后PlatformUninstall(arduino:samd)卸载平台。安装/升级/卸载的实现模式一致发起流式请求 → 循环Recv()→ 遇io.EOF结束 → 期间按消息类型打印DownloadProgress或TaskProgress。这是 arduino-cli 所有长耗时操作的标准消费模式可直接复用到自己的客户端中。3.5 编译与上传Compile请求携带Fqbn如arduino:samd:mkr1000、SketchPathhello目录与Verbose: true响应流中的OutStream/ErrStream分别对应编译过程的 stdout 与 stderrrpc/internal/client_example/main.go#L494-L531。Upload被注释掉原因是必须有真实板卡连接。若取消注释需要填充Port结构Address如/dev/ttyACM0与Protocol如serial。同样被注释的还有Debug流程——它使用双向流式接口Debug(stream DebugRequest) returns (stream DebugResponse)示例中向调试器发送info registers与quit命令并等待(gdb)提示符。3.6 板卡枚举与热插拔监听BoardListAll列出所有已安装平台提供的板卡示例用mkr过滤BoardList列出当前连接的板卡与匹配结果BoardListWatch服务端流式长连接监听板卡接入/移除事件。示例中事件类型取add/remove/error客户端在 goroutine 中消费事件流主协程用 10 秒定时器控制观察时长后退出rpc/internal/client_example/main.go#L601-L635。3.7 库管理下载、安装、升级、搜索、依赖解析、卸载库相关调用集中在WiFi101、Arduino_MKRIoTCarrier、ArduinoIoTCloud等真实库上流程如下UpdateLibrariesIndex更新库索引之后再次InitLibraryDownload(WiFi1010.15.2)仅下载到 staging 目录LibraryInstall(WiFi1010.15.1)安装指定版本随后以0.15.2再装一次完成版本替换LibraryInstall(Arduino_MKRIoTCarrier0.9.9)时设置NoDeps: true跳过依赖安装LibraryUpgradeAll升级全部已安装库LibrarySearch(audio)搜索库LibraryResolveDependencies(ArduinoIoTCloud)打印依赖名、要求版本与已安装版本LibraryList列出已安装库All: false、Updatable: falseLibraryUninstall(WiFi101)卸载。四、代理链路验证Docker Squid 实验README 用一组 Docker 命令演示如何在本地起一个 Squid 代理并确认 arduino-cli 的网络请求确实穿过代理。4.1 启动 Squid 容器docker run --name squid -d --restartalways \ --publish 3128:3128 \ --volume /path/to/squid.conf:/etc/squid/squid.conf \ --volume /srv/docker/squid/cache:/var/spool/squid \ sameersbn/squid:3.5.27-2其中squid.conf文件就在本目录rpc/internal/client_example/squid.conf启动时把卷路径指向它即可。该配置的关键规则包括http_port 3128监听端口与--publish 3128:3128对应acl SSL_ports port 443http_access deny CONNECT !SSL_ports仅允许对 443 端口的CONNECT隧道HTTPS 代理http_access allow localnet/allow localhost/allow all放行本地与局域网流量。4.2 实时观察代理日志docker exec -it squid tail -f /var/log/squid/access.log如果代理生效日志中会出现类似下面的记录——TCP_TUNNEL/200表示 arduino-cli 通过本地代理以隧道方式连接downloads.arduino.cc:443下载索引1612176447.893 400234 172.17.0.1 TCP_TUNNEL/200 116430 CONNECT downloads.arduino.cc:443 - HIER_DIRECT/104.18.28.45 - 1612176448.197 400245 172.17.0.1 TCP_TUNNEL/200 1621708 CONNECT downloads.arduino.cc:443 - HIER_DIRECT/104.18.28.45 - 1612176448.946 400256 172.17.0.1 TCP_TUNNEL/200 354882 CONNECT downloads.arduino.cc:443 - HIER_DIRECT/104.18.28.45 -日志字段依次为时间戳、请求耗时毫秒、来源 IP、隧道状态码、传输字节数、CONNECT 目标域名:443、以及实际出口方式。4.3 客户端如何配置代理main.go中callSetProxy通过设置项把代理写入配置rpc/internal/client_example/main.go#L244-L254client.SettingsSetValue(context.Background(), rpc.SettingsSetValueRequest{ Key: network.proxy, EncodedValue: http://localhost:3128, })客户端在主流程中先setProxy、再执行两次UpdateIndex——这正是为了用索引下载来验证代理配置已生效。在squid.conf与代理已就绪的前提下两次索引更新对应的 CONNECT 请求会连续出现在 access.log 中。从底层实现看network.proxy并非示例专属它由 internal/cli/configuration/network.go 的NetworkProxy()解析为*url.URL随后在NewHttpClient()与DownloaderConfig()中通过http.ProxyURL(proxy)注入 HTTP 传输层索引下载走的是 downloader 配置因此设置代理后重启 daemon 即可让所有下载类 RPC 走代理。示例客户端因为是临时进程、每次启动重新SettingsSetValue所以无需重启即可生效。五、常见疑问与排查要点连接失败怎么办确认 daemon 正在运行客户端log.Fatal会提示先执行arduino-cli daemon并检查端口是否被占用——daemon 启动时若端口被占会报 Address already in useinternal/cli/daemon/daemon.go为什么有些调用没有输出BoardListWatch观察 10 秒后自动退出Upload/Debug需要真实硬件默认被注释为什么代理日志看不到流量检查容器内/etc/squid/squid.conf是否为仓库提供的配置、3128端口映射是否成功以及network.proxy的 JSON 值是否带引号临时目录的生命周期客户端用defer os.RemoveAll(dataDir)在退出时清理临时数据目录因此每次运行都是全新环境可重复执行验证。六、延伸阅读RPC 服务与消息定义rpc/cc/arduino/cli/commands/v1/commands.proto、rpc/cc/arduino/cli/commands/v1/settings.protodaemon 服务端实现internal/cli/daemon/daemon.go网络代理与 HTTP 客户端实现internal/cli/configuration/network.go其他语言的调用方式可参考 rpc/internal/get_version_example 与 rpc/internal/client_example/hello/hello.ino 所在目录中的其他示例。简而言之client_example是理解 arduino-cli gRPC 接口的最佳起点——先arduino-cli daemon再跑client_example即可观察一整套真实调用配合 Docker Squid 与network.proxy设置还能顺带验证网络链路的代理行为。赞分享开发工具嵌入式【免费下载链接】arduino-cliArduino command line tool项目地址https://gitcode.com/gh_mirrors/ar/arduino-cli点击查看免费下载相关推荐从零开始使用samvit_huge_patch16.sa1b5分钟上手图像特征提取从零开始使用samvit_huge_patch16.sa1b5分钟上手图像特征提取 想要快速掌握 图像特征提取 的终极工具吗samvit_huge_patctonic-build 代码生成实战从 build.rs 到 gRPC 客户端与服务端tonic build 代码生成实战从 build.rs 到 gRPC 客户端与服务端 本篇技术指南以 tonic build/README.md https后端RPC框架FlatBuffers 与 gRPC 的 TypeScript 实践跑通 greeter 服务端与客户端FlatBuffers 与 gRPC 的 TypeScript 实践跑通 greeter 服务端与客户端 FlatBuffers 是一种零拷贝、内存高效的序列序列化跨平台编译器上一篇OpCore-Simplify15分钟搞定黑苹果EFI配置的智能助手下一篇OpenRAM开源SRAM编译器5步掌握专业级内存生成技术创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

Gopeed macOS 下载管理器完整指南:从安装包到容器化,3 条路径把工具跑起来

Gopeed macOS 下载管理器完整指南:从安装包到容器化,3 条路径把工具跑起来

Gopeed macOS 下载管理器完整指南:从安装包到容器化,3 条路径把工具跑起来 【免费下载链接】gopeed A fast, modern download manager for HTTP, BitTorrent, Magnet, and ed2k. Cross-platform, built with Golang and Flutter. 项目地址: https://g…

2026/10/5 2:19:31 阅读更多 →
5 分钟部署 Fast Note Sync Service:Docker 一键搭建 Obsidian 私有笔记同步服务器教程

5 分钟部署 Fast Note Sync Service:Docker 一键搭建 Obsidian 私有笔记同步服务器教程

5 分钟部署 Fast Note Sync Service:Docker 一键搭建 Obsidian 私有笔记同步服务器教程 【免费下载链接】fast-note-sync-service High-performance, low-latency note synchronization, online management, and remote REST API service platform. 项目地址: htt…

2026/10/5 2:18:31 阅读更多 →
CLRS 3.2 标准记号与常用函数习题精解:对数、阶乘、多重对数与斐波那契数的渐近分析

CLRS 3.2 标准记号与常用函数习题精解:对数、阶乘、多重对数与斐波那契数的渐近分析

文档教程示例工程 【免费下载链接】CLRS :notebook:Solutions to Introduction to Algorithms 项目地址: https://gitcode.com/gh_mirrors/cl/CLRS 点击查看 免费下载 本文基于 CLRS(《算法导论》)习题解答仓库中的 C03-Growth-of-Functions…

2026/10/5 2:18:31 阅读更多 →

最新新闻

从零构建 coding agent CLI:TUI、Agent Loop 与 LLM 函数调用实战

从零构建 coding agent CLI:TUI、Agent Loop 与 LLM 函数调用实战

1. 从“pi”这个标题说起:一个极简命名背后的技术野心第一次看到“pi”这个项目标题,很多人会本能地联想到数学常数,或者树莓派(Raspberry Pi),再或者某个缩写。但如果你最近在开发者社区里泡过&#xff0c…

2026/10/5 11:16:56 阅读更多 →
ZYNQ EMIO调试UART完整指南:从引脚规划到串口实测

ZYNQ EMIO调试UART完整指南:从引脚规划到串口实测

ZYNQ 开发里有两件事几乎绕不开:一件是调试,一件是串口。做调试离不开 UART,做 UART 调试又绕不开 MIO 和 EMIO 的选择。我最早做 ZYNQ 的时候,习惯直接用 PS 端 MIO 接出来的 UART0,板子一上电就能在串口终端里看到 B…

2026/10/5 11:16:56 阅读更多 →
跨学科仿生设计:AI代理模型与多尺度仿真融合的数据驱动优化框架

跨学科仿生设计:AI代理模型与多尺度仿真融合的数据驱动优化框架

简介:这是一份聚焦跨学科融合仿生设计的系统性技术文档,面向机器人、新材料与AI交叉领域的研究者、工程师及高年级学生,系统讲解如何将机器学习、深度学习、材料基因组、多尺度建模与拓扑优化等方法整合到仿生设计全流程中。文档共593页&…

2026/10/5 11:16:56 阅读更多 →
智慧工厂AI安防平台设计:从架构到落地全流程指南

智慧工厂AI安防平台设计:从架构到落地全流程指南

简介:《AI赋能的智慧工厂安防平台建设方案》演示文稿是一份面向智慧工厂安防规划与智能制造升级的方案型资源,适合安防系统集成商、工厂信息化人员及管理者参考,可用于解决传统工厂安防管理分散、响应滞后、智能化程度不足等问题。内容围绕综…

2026/10/5 11:16:56 阅读更多 →
K8s服务发现与网络策略:读懂原理到实战避坑指南

K8s服务发现与网络策略:读懂原理到实战避坑指南

1. 前言:为什么服务发现和网络策略是K8s运维的两道必答题无论你是刚把第一个Pod跑起来,还是已经在生产环境里折腾了大半年,Kubernetes的服务发现和网络策略一定都绕不开。简单说,服务发现解决的是“流量到底该打到哪个Pod上”的问…

2026/10/5 11:16:56 阅读更多 →
Superpowers工作流:AI原生开发的认知增强层实战指南

Superpowers工作流:AI原生开发的认知增强层实战指南

1. 项目概述:Superpowers 不是超能力,而是开发者工具链的“认知增强层”你搜“superpowers”时看到的满屏 Claude Code、Antigravity、Codex CLI、Cursor,不是漫威电影彩蛋,也不是某个神秘组织的代号——这是2024年中后期&#xf…

2026/10/5 11:15:55 阅读更多 →

日新闻

马斯克杀回智能体战场,Grok 4.5万亿参数撑腰,Cursor接手数字白领项目:用TaoToken统一Key跑通多模型Agent工作流

马斯克杀回智能体战场,Grok 4.5万亿参数撑腰,Cursor接手数字白领项目:用TaoToken统一Key跑通多模型Agent工作流

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

2026/10/5 0:00:22 阅读更多 →
AI编程工具插件机制详解:plugin.json配置与加载失败排查指南

AI编程工具插件机制详解:plugin.json配置与加载失败排查指南

1. 从“plugins”这个词说起:它到底在解决什么问题如果你最近在折腾 AI 编程工具,尤其是 Cursor、Codex CLI、Claude Code 这类带 CLI 的编辑器或命令行助手,那你大概率绕不开一个词——plugins。这个词本身不新鲜,从浏览器到 IDE…

2026/10/5 0:00:23 阅读更多 →
第26课:OpenClaw|日志审计与问题诊断:把日志链路改到 TaoToken 的排查清单

第26课:OpenClaw|日志审计与问题诊断:把日志链路改到 TaoToken 的排查清单

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

2026/10/5 0:00:23 阅读更多 →

周新闻

KT148A语音芯片外挂8002D功放的工程实践指南

KT148A语音芯片外挂8002D功放的工程实践指南

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

2026/10/5 5:06:42 阅读更多 →
LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

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

2026/10/5 1:10:22 阅读更多 →
ARM架构深度解析:从RISC设计理念到交叉编译实战

ARM架构深度解析:从RISC设计理念到交叉编译实战

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

2026/10/5 3:06:17 阅读更多 →

月新闻

我发现了一个新思路:用 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/4 11:40:45 阅读更多 →
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/4 9:43:54 阅读更多 →
黑夜航拍船只数据集训练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/4 20:14:29 阅读更多 →