Skip to content

pubgo/zigo

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

110 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ZigBridge

一个最小、可复用、可扩展的 Go ↔ Zig 跨语言调用框架。

核心目标是把跨语言调用抽象成一个极简接口:

  • 输入:[]byte
  • 输出:[]byte
  • 调用:Invoke(method, body) -> (status, result)

为什么是 ZigBridge

  • 极简调用模型:单函数接口,低认知负担
  • 进程隔离:Go 与 Zig 通过 Unix Socket 通信,无 CGO 依赖
  • 内存边界清晰:各进程独立管理内存,通过 FlatBuffers 序列化传输
  • 可扩展:模块化 method 注册,支持一元调用与流式接口

快速开始

环境要求

  • Zig 0.16+
  • Go 1.25+
  • macOS / Linux(当前仓库已在 macOS 验证)
  • flatc(仓库提供 tools/flatc,用于 Go 侧 schema 生成)

构建与运行

ZigBridge 采用 Unix Socket 进程间通信,需先启动 Zig 服务端,再运行 Go 客户端。

make schema    # 生成 Go/Zig FlatBuffers 代码
make all       # 构建 Zig + Go
make test      # 运行核心测试

运行示例(自动管理 Zig 服务端生命周期):

# SQLite 示例
make -C examples/sqlite-app run

# AAC 编码示例(编码真实 WAV 音频文件)
make -C examples/aac-codec run

zigo CLI(推荐)

安装 zigo 开发 CLI 后可简化日常操作:

go install ./cmd/zigo/

zigo init my-app         # 创建新模块脚手架
zigo build my-app        # 构建
zigo run sqlite-app      # 运行示例
zigo test aac-codec      # 运行测试
zigo serve sqlite-app    # 前台启动 Zig 服务端(调试用)

详见 cmd/zigo/README.md


项目结构

zig/
  lib.zig          # Zig 核心:dispatch 路由 + stream runtime + socket 服务
  bridge_fb.zig    # FlatBuffers 编解码
  build.zig        # Zig 构建脚本
  generated/fb/    # 生成的 FlatBuffers Zig 代码
go/zig/
  zig.go           # Go 核心 API:InvokeUnpack / Metrics / InvokeOption
  bridge.go        # BridgeRequest/Response FlatBuffers 编解码
  client.go        # Client:Zig 子进程生命周期管理
  driver.go        # Driver 接口定义
  driver_socket.go # Unix Socket 传输实现
  monitor.go       # 资源监控:ProcessMetrics / ResourceLimits
  fbutil.go        # FlatBuffers 辅助:Pack/Unpack/Builder Pool
  stream.go        # 流式接口编码与调用
  status.go        # 状态码定义
  fb/              # 生成的 FlatBuffers Go 代码
schema/
  all.fbs          # 桥接协议 schema(request/response/stream)
examples/
  sqlite-app/      # SQLite 封装示例
  aac-codec/       # AAC 音频编码示例
cmd/
  zigo/            # zigo 开发 CLI(脚手架、构建、运行、测试)
tools/
  flatc            # FlatBuffers 编译器
  zigcurl/         # 极简 HTTPS 下载工具(纯 Zig,184 KB)
  mqttcli/         # MQTT 命令行客户端(pub/sub;full ~460 KB / slim ~157 KB)
  natscli/         # NATS 命令行客户端(pub/sub/req/reply,~600 KB)
  zrpc/            # zrpccli — Protobuf RPC over NATS(call/serve,Zig ↔ Go)
  noisecli/        # Noise Protocol 命令行工具(genkey/serve/dial,~250 KB)
  sqlitecli/       # SQLite CLI(full ~1 MB + slim ~0.9 MB,静态嵌入 SQLite)
  duckdbcli/       # DuckDB CLI(静态嵌入 DuckDB,via zuckdb.zig)
  tflitecli/       # TensorFlow Lite CLI(info / detect,~250 KB + libtensorflowlite_c.so)
  onnxcli/         # ONNX Runtime CLI(info / detect YOLOv8,+ libonnxruntime.so)
  grpccli/         # gRPC + protobuf 验证 CLI(见 example/)
Makefile           # 统一构建入口

通信架构

ZigBridge 采用 Unix Socket + 长度前缀帧 作为传输层:

sequenceDiagram
    participant G as Go Client
    participant S as Unix Socket
    participant Z as Zig Server

    G->>G: Build BridgeRequest (FlatBuffers)
    G->>S: [4 bytes BE length][payload]
    S->>Z: dispatch(method, payload)
    Z->>Z: Route to handler
    Z->>S: [4 bytes BE length][BridgeResponse]
    S->>G: Parse response
    G->>G: Return (status, result)
Loading

传输协议:

  • 帧格式:[4 bytes big-endian uint32 长度][FlatBuffers payload]
  • 默认 socket 路径:/tmp/zigbridge.sock(可通过 ZIGBRIDGE_SOCK 环境变量覆盖)
  • Go 侧使用 SocketDriver,支持 buffer 复用,单次 write 合并

核心接口

Go 层

// Invoker 是调用 Zig handler 的核心接口
type Invoker interface {
    Invoke(method string, body any, opts ...InvokeOption) (uint32, []byte)
}

// 通过 Driver 创建 Invoker
inv := zig.NewInvoker(driver)
// 或通过 Client(自动管理子进程)
client, _ := zig.NewClient(&zig.ClientConfig{BinPath: "path/to/zigbridge"})

// 带类型解码的一元调用(辅助函数)
InvokeUnpack[T](inv Invoker, method string, body any, table Unpackable[T], opts ...) (*T, uint32, error)

// 选项
WithRequestID(id uint64) InvokeOption
WithHeaders(h []*fb.HeaderEntryT) InvokeOption

流式 API(编译期 feature gate,默认关闭):

  • StreamOpen / StreamSend / StreamRecv / StreamClose / StreamCancel(MVP 主线)
  • StreamWindowUpdate / StreamStats(实验扩展)

指标

ResetMetrics()
GetMetrics() Metrics  // Calls, BytesIn, BytesOut (Go 侧 atomic 计数)

状态码

代码 常量 含义
0 StatusOK 成功
1 StatusBadRequest 请求格式错误
2 StatusBridgeShortReply 响应不完整
100 StatusUnknownMethod 未知 method
110~114 StatusStream* 流式错误

可通过 zig.StatusText(code) 获取文本描述。

协议与代码生成(FlatBuffers)

  • 桥接协议 schema 位于 schema/request.fbsresponse.fbsstream.fbs
  • make schema 同时生成 Go 和 Zig 代码
  • 运行时使用 FlatBuffers 作为 Go ↔ Zig 序列化层

Go 侧编码辅助(go/zig 包内)

FlatBuffers 辅助工具已合并到 go/zig 包:

  • Pack(Packable) []byte:使用池化 Builder 序列化
  • Unpack[T](buf, table) (*T, bool):反序列化
  • PutU16LE / PutU32LE / ReadU32LE:小端字段编解码

业务层通过 examples/<app>/go/<app>/codec.go 封装 DTO,不直接依赖生成 API。


性能基准测试

测试环境:macOS amd64, Intel i5-1038NG7, 2026-05-23

核心桥接层

Benchmark ns/op B/op allocs/op
BuildBridgeRequest_Small 328 160 2
BuildBridgeRequest_1KB 460 1,233 2
BuildBridgeRequest_WithHeaders 782 400 5
ParseBridgeResponse 18 0 0
RoundTripEncodeDecode 390 656 2

AAC 编码(via Unix Socket)

Benchmark ns/op MB/s B/op allocs/op
EncOpenClose 242,269 568 16
EncEncode_Stereo44k 194,334 21.08 9,992 8
EncEncode_Mono16k 180,642 11.34 4,832 8
EncEncode100Frames 20,607,525 19.88 999,871 804
EncFullPipeline_10Frames 2,077,092 104,624 97

SQLite(via Unix Socket)

Benchmark ns/op B/op allocs/op
OpenClose 143,656 528 14
Exec_Insert 2,145,282 452 10
Exec_Select 2,244,883 1,052 9
ExecBatch 2,305,023 2,178 39
Exec_SimpleQuery 2,130,739 344 9
ConcurrentExec 2,119,229 346 9

运行基准测试

# 核心桥接层(纯编解码,无需 Zig 服务端)
go test -bench=. -benchmem ./go/zig/

# AAC(需 Zig 服务端,Makefile 自动管理)
cd examples/aac-codec && make test

# SQLite
cd examples/sqlite-app && make test

Make 任务

根目录

命令 说明
make schema 生成 Go/Zig FlatBuffers 代码
make all 构建 Zig + Go
make test 运行核心测试
make zig 仅构建 Zig 服务端
make go 仅构建 Go
make zigo 构建 zigo CLI 到 $GOPATH/bin
make clean 清理构建产物

示例

命令 说明
make -C examples/sqlite-app run 运行 SQLite demo
make -C examples/sqlite-app test 运行 SQLite 测试
make -C examples/aac-codec run 编码 3 种 WAV 文件 → AAC
make -C examples/aac-codec test 运行 AAC 测试

示例 Makefile 自动管理 Zig 服务端生命周期(启动 → 等待就绪 → 运行 Go → 清理)。


常见问题

1) 连接失败:cannot connect to zigbridge

确认 Zig 服务端已启动:

# 手动启动
zig/zig-out/bin/zigbridge &
# 或使用 make(自动管理)
make -C examples/sqlite-app run

2) 修改 Zig 代码后行为未变

需要重新构建 Zig 服务端:

cd zig && zig build
# 然后重启服务端进程

3) Socket 文件残留

rm -f /tmp/zigbridge.sock

扩展新模块

使用 zigo init 一键创建模块脚手架:

zigo init my-app

生成 examples/my-app/ 完整目录(schema、Zig handler、Go API、Makefile、README),然后:

  1. 编辑 examples/my-app/schema/my-app.fbs — 定义业务数据结构
  2. 编辑 examples/my-app/zig/my_app.zig — 实现 handler 并注册 method
  3. 编辑 examples/my-app/go/myapp/myapp.go — 封装 Go DTO API
  4. zigo build my-app — 构建
  5. zigo test my-app — 测试

详见 cmd/zigo/README.md


内置工具

zigcurl

tools/zigcurl/ 是一个极简 HTTPS 下载工具,纯 Zig 实现,零外部依赖,适合嵌入式场景。

指标
语言 Zig 0.16
功能 HTTP/HTTPS GET 下载
ReleaseSmall 497 KB(完全静态)
+ UPX 压缩 184 KB
TLS 内置 TLS 1.3(无 OpenSSL 依赖)
依赖 仅 libSystem(macOS)/ 无(Linux 静态)
# 构建
cd tools/zigcurl && zig build -Doptimize=ReleaseSmall

# 构建 + UPX 压缩(需安装 upx)
zig build -Doptimize=ReleaseSmall -Dupx=true

# 使用
./zig-out/bin/zigcurl https://example.com -o page.html
./zig-out/bin/zigcurl -v https://httpbin.org/get

支持选项:-o <file>(输出文件)、-v(verbose)、-h(帮助)。

mqttcli

tools/mqttcli/ 是 MQTT 命令行客户端,用法接近 mosquitto_pub / mosquitto_sub,纯 Zig 实现。

指标 mqttcli(full) mqttcli-slim
ReleaseSmall ~460 KB(macOS)/ ~176 KB UPX(Linux amd64) ~157 KB(macOS)
传输 mqtt:// + mqtts://(TLS) mqtt:// only
协议 MQTT 5(默认)+ MQTT 3.1.1(--mqtt-version 3 MQTT 5 only
场景 通用 / 云端 TLS 嵌入式 Linux、局域网明文 broker
# 构建(同时产出 mqttcli + mqttcli-slim)
make mqttcli

# 发布 / 订阅
mqttcli pub -h 127.0.0.1 -t hello -m world
mqttcli-slim pub -h 127.0.0.1 -t telemetry -m '{"t":22}'

# TLS(仅 full)
mqttcli pub --url mqtts://broker:8883 --cafile ca.pem -t sensors/temp -m 22.5

编译裁剪:-Dtls=false-Dmqtt311=false-Dslim=true(见 tools/mqttcli/README.md)。

发布:打 tag mqttcli/v* 触发 release workflow,产物为多平台 .tar.gz + checksums.txt

详见 tools/mqttcli/README.mddocs/mqttcli.md

natscli

tools/natscli/ 是基于 nats-io/nats.zig 的 NATS 命令行客户端(不含 JetStream)。

子命令 说明
pub 发布一条消息
sub 订阅并打印
req 单次 request/reply
reply 监听并响应(默认 echo)
make natscli
natscli pub -s hello -m world
natscli sub -s hello
natscli reply -s echo.svc &
natscli req -s echo.svc -m ping

发布:打 tag natscli/v* 触发 release workflow,产物为 linux_amd64 / arm64 / armv7 / darwin 的 .tar.gz + checksums.txt(当前 v0.1.1)。

armv7 通过 patches/ 对 fetch 后的 nats.zig 做构建时兼容;计划向上游提 PR 后移除。详见 docs/natscli.md

详见 tools/natscli/README.mddocs/natscli.md

zrpccli

tools/zrpc/Protobuf unary RPC over NATS 的 CLI 与 codegen(zrpccli),与 Go 服务共用 subject / queue / protobuf wire。

子命令 说明
serve 注册生成服务,监听 NATS request-reply
call JSON 请求调用 echo.Echo/Echo 等 rpc
make zrpccli
nats-server -p 4222 &
zrpccli serve
zrpccli call echo.Echo/Echo '{"message":"hello"}'

发布:打 tag zrpccli/v* 触发 release workflow仅分发 zrpccli(linux_amd64 / arm64 / armv7 / darwin .tar.gz + checksums.txt)。

详见 tools/zrpc/README.mddocs/zrpc.md

noisecli

tools/noisecli/ 是基于 zigo 内维护 noizlib/noiz/)的 Noise Protocol 命令行工具,用于密钥生成、握手调试与加密 echo 联调。

子命令 说明
genkey 生成 X25519 密钥对
serve 监听 TCP,握手后加密 echo
dial 连接、握手、发送一条消息并打印响应
handshake 仅握手,输出 JSON(hash + 耗时)
make noisecli
noisecli genkey -o server.key --pub server.pub
noisecli serve -p 7000 --local-key server.key &
echo hello | noisecli dial 127.0.0.1:7000 --local-key client.key --stdin

协议库在 lib/noiz/src/ 内维护(Zig 0.16 适配 + cacophony 向量测试)。发布:打 tag noisecli/v* 触发 release workflow,产物为 linux_amd64 / arm64 / armv7 / darwin 的 .tar.gz + checksums.txt

详见 tools/noisecli/README.mddocs/noisecli.md

sqlitecli

tools/sqlitecli/ 是基于 zqlite.zig 的 SQLite 命令行客户端;SQLite 以 amalgamation 静态编译进二进制,不依赖系统 libsqlite3。默认产出 sqlitecli(含 FTS5)与 sqlitecli-slim(更小、无 FTS5);RTREE 等可在 build.zig 逐步打开(见 docs/sqlitecli.md)。

子命令 说明
exec 执行 SQL(支持多语句)
query SELECT 并格式化输出
shell 交互 REPL(.tables / .schema / …)
make sqlitecli
sqlitecli exec -d ./app.db -e "CREATE TABLE t (id INTEGER PRIMARY KEY, v TEXT)"
sqlitecli query -d ./app.db -e "SELECT * FROM t" --format csv --header
sqlitecli shell -d ./app.db

首次构建若缺少 lib/sqlite3.cmake sqlitecli 会自动运行 scripts/fetch-sqlite.sh

发布:打 tag sqlitecli/v* 触发 release workflow,产物为 linux_amd64 / arm64 / armv7 / darwin 的 .tar.gz + checksums.txt

详见 tools/sqlitecli/README.mddocs/sqlitecli.md

duckdbcli

tools/duckdbcli/ 是基于 zuckdb.zig 的 DuckDB 命令行客户端;DuckDB 在构建时由 zuckdb 拉取并静态链接,不依赖系统 libduckdb。接口与 sqlitecli 对齐:exec / query / shell

子命令 说明
exec 执行 SQL(支持多语句)
query SELECT 并格式化输出
shell 交互 REPL(.tables / .schema / …,基于 duckdb_tables()
make duckdbcli
duckdbcli exec -d ./app.duckdb -e "CREATE TABLE t (id INTEGER, name VARCHAR)"
duckdbcli query -d ./app.duckdb -e "SELECT * FROM t" --format csv --header
duckdbcli shell -d ./app.duckdb

首次构建会编译 DuckDB 源码,耗时较长;后续构建走 Zig 缓存。

发布:打 tag duckdbcli/v* 触发 release workflow,产物为 linux_amd64 / arm64 / armv7 / darwin 的 .tar.gz + checksums.txt

详见 tools/duckdbcli/README.mddocs/duckdbcli.md

tflitecli

tools/tflitecli/ 是 TensorFlow Lite 命令行工具:动态链接预构建的 libtensorflowlite_c.so(TFLite v2.17.1),Zig 侧约 ~250 KB(ReleaseSmall)。用于查看 .tflite 元数据、在图片上跑 SSD 检测(Coral / axis-model-zoo 的 postprocess 模型)。

子命令 说明
info 打印输入/输出 tensor 名称、dtype、shape
detect SSD 目标检测(--image / --labels / --threshold / --draw
make tflitecli                    # macOS:远程 travel 编译并同步
make tflitecli-smoke              # info + detect 冒烟

export LD_LIBRARY_PATH=tools/tflitecli/lib/tflite/lib
tflitecli info testdata/ssd_mobilenet_v2_coco_quant_postprocess.tflite
tflitecli detect testdata/ssd_mobilenet_v2_coco_quant_postprocess.tflite \
  --image photo.jpg --labels testdata/coco_labels.txt --threshold 0.5 --draw out.png

首次构建:macOS 无法链接 Linux .somake tflitecli 会 rsync 到 SSH 主机 travel(或 TFLITE_REMOTE=dev)编译;Linux 开发机可先 bash tools/tflitecli/scripts/build-tflite-remote.sh 同步 TFLite 库再本地 zig build

部署到嵌入式 Linux 需同时拷贝二进制、libtensorflowlite_c.so 与模型,运行时设置 LD_LIBRARY_PATH

详见 tools/tflitecli/README.mddocs/tflitecli.md

onnxcli

tools/onnxcli/ 是 ONNX Runtime 命令行工具:info / YOLO detect / 通用 run。macOS 与 Linux 本机构建;算力盒子可用 make onnxcli-linuxONNX_REMOTE)。

make onnxcli
make onnxcli-smoke

export LD_LIBRARY_PATH=tools/onnxcli/lib/onnx/lib
onnxcli detect testdata/yolov8n.onnx --image testdata/bus.jpg \
  --labels testdata/coco_labels.txt --json --timing

可与 playcli snap 管道联调(snap 出图 → onnxcli 检测)。详见 tools/onnxcli/README.mddocs/onnxcli.md


相关文档

为便于分层阅读,文档拆分如下:

About

一个最小、可复用、可扩展的 Go ↔ Zig 跨语言调用框架

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors