OmniBinder — 让嵌入式多服务协作,回归一行代码的简单

OmniBinder — 让嵌入式多服务协作,回归一行代码的简单

面向 Linux / Windows(可扩展鸿蒙/Android) 多服务协作系统服务通信中间件(跨版/同板)

统一 IDL · Stub/Proxy 自动生成 · 同机 SHM 直通 · 跨板 TCP 自适应 · omni-cli 一键诊断


一、为什么会有 OmniBinder?

在嵌入式、工业和边缘计算场景中,一个完整系统从来不是一个单体程序。

一台工业机器人内部,传感器采集、运动规划、安全监控、日志记录是四个独立的服务进程;一座充电桩里,功率控制、计费结算、屏幕交互、温度监控分散在不同模块上;一辆工程机械的驾驶舱内,三块屏幕、一个数据融合单元、一个诊断接口各自运行在不同的控制器上。

每个场景都是多服务协作系统。 但现实是——没有统一的通信层。

在这里插入图片描述

协议碎片化:6 个服务,30 条自定义通道。每个服务各自定义一套通信协议,接口不统一,大量重复造轮子。

跨板调试困难:两块板子之间出了问题,日志只有原始的 hex 字节,没有结构化输出,定位一个跨板通信 Bug 动辄数小时。

服务状态不可见:一个服务挂了,其他服务不知道,开发者也发现不了——直到用户报告故障。没有心跳检测,没有死亡通知。

部署拓扑一变,代码就要重写:本地测试时 4 个服务跑在同一块板子上,共享内存工作得好好的。部署到生产环境,拆成两块板子——共享内存不通了,不得不把整层通信代码改成 TCP。下次再加一块板子,又要改一遍。

这就是我开发 OmniBinder 的原因。


二、OmniBinder 是什么?

OmniBinder 是一个面向嵌入式 Linux 与局域网分布式场景的服务通信中间件。它提供了一套统一的模型,让多个服务进程——无论在同设备、跨板、还是跨设备——以一致的方式完成注册、发现、RPC 调用、事件广播和状态感知。

一句话概括:OmniBinder 是在分布式服务之间充当通信桥梁的中间件,让服务与服务之间的连接、调用和数据分发标准化。

在这里插入图片描述

适用行业

场景说明
工业机器人传感器→算法→控制→安全→日志,同设备多板卡多服务协作
新能源充电桩功率控制、计费结算、屏幕交互、温度监控,桩内多模块通信
工程机械多屏联动、数据融合、远程诊断,驾驶舱内多控制器互联
车载智能座舱中控屏、仪表盘、ADAS、娱乐系统,跨 ECU 域控制器通信
边缘计算网关多个子设备数据的汇聚、转发、协议桥接,局域网服务网关

三、功能全览

在这里插入图片描述

维度能力
接口定义统一 .bidl IDL 语言,支持基础类型、结构体、数组、嵌套类型
代码生成C++ Stub(服务端骨架)+ C++ Proxy(客户端代理)+ C 接口
服务管理注册 / 发现 / 注销,中心化 ServiceManager
远程调用同步 RPC(请求/响应)+ 单向调用(one-way)
事件广播发布/订阅 Topic 机制,一对多实时分发
死亡通知服务异常退出时自动通知所有关注者
自动重连服务恢复后自动重连,支持指数退避策略
传输自适应同设备优先 SHM,跨设备走 TCP,零代码切换
诊断工具omni-cli 命令行,支持 list / info / call / watch 四个命令
跨平台Linux + Windows 双平台支持
零依赖C++11 编译,不依赖任何第三方库

四、运行时架构

在这里插入图片描述

控制面与数据面分离

OmniBinder 采用经典的两层架构:

  • ServiceManager(控制面):中心化的注册发现枢纽。所有服务启动时向它注册,客户端通过它发现目标服务。同时负责心跳监控、死亡通知和话题管理。

  • 数据通道(数据面):服务之间直连通信。根据部署拓扑自动选择传输方式——

    部署关系传输方式典型延迟
    同设备(同一机器)共享内存 (SHM)68 μs
    跨板(同一局域网)TCP200-500 μs
    切换方式自动,零代码改动

omni-cli:运行时诊断工具

四个命令覆盖日常运维:

$ omni-cli list
NAME             HOST        PORT    STATUS
SensorService    127.0.0.1   8097    ONLINE
AlgoService      127.0.0.1   8100    ONLINE
Total: 2 services online

$ omni-cli info SensorService
Service: SensorService
  Host:    127.0.0.1
  Port:    8097
  Status:  ONLINE
  Interface: ISensor (id=0x10000001)
    Methods:
      - GetLatestData() -> SensorData  (id=0x00000001)
      - SetThreshold(ControlCommand) -> Status  (id=0x00000002)

$ omni-cli call SensorService GetLatestData
Calling SensorService.GetLatestData() ...
  interface_id = 0x10000001
  method_id    = 0x00000001
Response (status=OK, 38 bytes, 0.81 ms):
  { "sensor_id": 1, "temperature": 23.55, "humidity": 61.95, "location": "Room-A" }

$ omni-cli watch SensorService
Watching diagnostic data from SensorService...
[Diagnostic] invoke ISensor::GetLatestData  seq=1042  direction=REQUEST
[Diagnostic] invoke ISensor::GetLatestData  seq=1042  direction=REPLY

一行命令,看清所有服务状态与调用链路,无需重启,无需额外部署。


五、开发体验

在这里插入图片描述

第一步:定义接口(.bidl IDL 文件)

package demo;

struct SensorData {
    int32   sensor_id;
    float64 temperature;
    float64 humidity;
    string  location;
}

service SensorService {
    SensorData GetLatestData();
    Status     SetThreshold(ControlCommand cmd);
    int32      GetSensorCount();
    publishes  SensorUpdate;
}

第二步:自动生成代码

$ ./omni-idlc sensor.bidl --lang cpp --outdir gen/
✓ sensor.bidl.h          # 类型定义
✓ SensorServiceStub      # 服务端骨架
✓ SensorServiceProxy     # 客户端代理

第三步:写业务逻辑

服务端——继承自动生成的 Stub,实现接口即可:

class MyService : public SensorServiceStub {
    SensorData GetLatestData() override { return readSensor(); }
};
runtime.registerService(&service);   // 一行注册
runtime.publishTopic("SensorUpdate"); // 一行发布话题

客户端——使用自动生成的 Proxy:

SensorServiceProxy proxy(runtime);
proxy.connect();                         // 一行连接
proxy.GetLatestData(&data);              // 一行 RPC 调用
proxy.SubscribeSensorUpdate(callback);    // 一行订阅广播
proxy.OnServiceDied([]{ reconnect(); });  // 一行死亡通知

从 IDL 定义到跑通第一个 RPC,只需三步。同设备自动走 SHM,跨板自动走 TCP——零代码切换。


六、服务协作关系

在这里插入图片描述

在一个典型的嵌入式系统中,服务不是孤立存在的。以上图为例——核心算法服务作为中枢,接收视频、语音、人脸、CAN 数据四个上游服务的输入,处理后输出到 HMI 服务展示;电源管理服务监控所有服务的功耗;升级服务负责所有服务的固件 OTA 更新。

通过 omni-cli,你可以随时查看任意服务的心跳状态、接口定义、调用链路和实时诊断数据流。


七、性能数据

测试项样本数平均值P95P99
RPC Echo (0 bytes)100068.5 μs85 μs101 μs
RPC Echo (256 bytes)100068.3 μs86 μs110 μs
RPC Echo (1024 bytes)100070.5 μs89 μs109 μs
RPC Echo (4096 bytes)100074.2 μs97 μs122 μs
RPC Echo (8192 bytes)100086.4 μs111 μs138 μs
RPC Add (2 x int32)100073.6 μs93 μs109 μs
Topic pub/sub (64 bytes)100028.4 μs52 μs69 μs
Topic pub/sub (8192 bytes)100038.6 μs64 μs84 μs

测试环境:Windows WSL2 Ubuntu 20.04 · SHM eventfd 事件驱动 · 1000 轮 · 预热 50 轮 · 100% 成功率。


八、快速上手

# 编译
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build -j$(nproc)

# 启动 ServiceManager
./build/target/bin/service_manager

# 启动服务端
./build/target/example/example_cpp_sensor_server

# 启动客户端
./build/target/example/example_cpp_sensor_client

九、开源与许可

  • 开源地址github.com/TaoistLuo/OmniBinder
  • 许可协议:MIT
  • 编译标准:C++11,同时提供完整 C 接口
  • 支持平台:Linux(epoll/eventfd/SHM)+ Windows(IOCP/Named Pipe)
  • 外部依赖:零

如果你正在构建一个由多个服务组成的嵌入式或分布式系统,希望它们之间有一层统一的通信桥梁——OmniBinder 就是为此设计的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值