自动驾驶(八十六)---------通信中间件Fdbus

最近在对接各供应商的SOA软件架构和舱驾融合方案,发现无论是在智驾底软,还是智驾和座舱的通信,基本都是采用了fdbus的通信方案,因此总结一下Fdbus的相关内容。本文分为以下三部分介绍Fdbus:1. 什么是Fdbus,它和SOMEIP的区别是什么?2. Fdbus通信机制,Protobuf的关系。 3. 给出一个本地通信代码示例,以及应用层如何调用接口实现通信。

1. 什么是Fdbus

Fdbus 全称 Fast Distributed Bus,提供IPC+RPC功能。适用于多种OS,FDBus 的设计目标是提供高性能、低延迟和低资源开销的消息传递机制。它支持多种传输协议和底层网络架构,使得开发者可以在不同平台和环境中使用同一套接口进行通信,简化了跨平台开发的复杂性。

  • 高性能和低延迟:FDBus 的轻量级设计和高效的消息传递机制,确保了低延迟和高吞吐量,适用于对实时性要求高的应用场景。

  • 跨平台支持:FDBus 支持多种操作系统和硬件平台,包括 Windows、Linux 和嵌入式系统。开发者可以在不同平台之间无缝迁移,降低开发成本和时间。

  • 模块化和可扩展性:FDBus 的模块化设计使得系统可以根据需要进行扩展和定制。开发者可以根据具体需求,添加或修改功能模块,增强系统的灵活性。

  • 易于集成:FDBus 提供了简单易用的 API,方便与现有系统进行集成。开发者可以快速上手,并在现有项目中加入 FDBus 的消息传递功能。

  • 可靠性和安全性:FDBus 通过多种机制保证消息传递的可靠性和安全性,如消息确认、重传机制和加密通信,确保了数据传输的可靠性和安全性。

基于以上原因,FDBus在域控中成为了关键通信机制,实现不同功能域之间的高效数据交换和协同工作。SOMEIP也是自动驾驶中另一种重要的通信方式,以下是 FDBus 和 SOME/IP 的主要区别:

  • 设计理念不同:FDBus注重轻量级、灵活性和高性能,适用于各种嵌入式和分布式系统。SOME/IP:侧重于服务导向的通信,适用于复杂的汽车电子系统,支持服务发现和描述。

  • 协议层次不同:FDBus在传输层之上提供消息传递机制,可以基于不同的底层网络协议(如 TCP、UDP 等)进行通信。SOME/IP基于 IP 协议,提供服务发现、服务描述和服务调用机制,适用于服务导向的通信模式。

  • 复杂度和资源开销:FDBus轻量级设计,资源开销低,适用于资源受限的嵌入式系统。SOME/IP提供丰富的服务导向功能,适用于复杂系统,但相对复杂度和资源开销较高

2. Fdbus通信机制

Fdbus主要组件分为:

  • FDBus Context:FDBus的上下文管理器,负责管理整个消息传递系统的生命周期。它初始化并启动消息处理线程,管理消息队列和事件循环。

  • FDBus Server:服务器端组件,负责接收客户端的连接和消息请求,并处理这些请求。服务器通过绑定特定的URL来暴露服务,等待客户端连接。

  • FDBus Client:客户端组件,负责连接到指定的服务器URL,并发送消息请求。客户端可以订阅服务器的特定消息,以便接收通知或广播消息。

  • FDBus Message:消息对象,封装了要传递的数据和元信息。消息可以在客户端和服务器之间传递,并且可以携带负载数据。

  • FDBus Event:事件对象,表示特定的事件或通知。事件可以从服务器广播到多个客户端,或者在客户端之间传播。

通信之前需要建立客户端和服务端的通信,要建立通讯需要指定IP和端口,FDBus使用URL来标识通信端点,URL的格式通常为fdbus://[IP地址]:[端口号]/[服务名]。服务器通过绑定特定的URL来暴露服务,客户端通过连接特定的URL来访问服务。

综上,Fdbus通信的步骤为:

  • URL解析:客户端和服务器在启动时,会解析指定的URL,提取出IP地址、端口号和服务名等信息。

  • 连接管理:客户端根据解析出的IP地址和端口号,尝试与服务器建立连接。一旦连接建立,客户端和服务器之间就可以通过消息进行通信。

  • 消息路由:FDBus在内部维护一个消息路由表,映射每个服务名到相应的处理函数。消息到达服务器后,会根据服务名查找对应的处理函数,并调用该函数处理消息。

  • 消息创建:客户端或服务器创建一个FDBus消息对象,封装要传递的数据。

  • 消息发送:客户端调用invoke方法,将消息发送到服务器。服务器接收到消息后,调用相应的处理函数。

  • 消息处理:服务器处理消息,根据消息类型和内容执行相应的操作,然后创建一个回复消息对象。

  • 消息回复:服务器调用reply方法,将回复消息发送回客户端。客户端接收到回复消息后,调用相应的回调函数处理回复数据。

  • 事件广播:服务器可以创建事件对象,并调用broadcast方法,将事件广播给所有订阅该事件的客户端。

Protocol Buffers(Protobuf)是Google开发的一种高效、可扩展的序列化协议。它用于结构化数据的序列化和反序列化,广泛应用于数据存储和网络通信。

  • 序列化:将数据结构转换为二进制格式,以便高效传输。
  • 反序列化:将二进制格式的数据还原为原始数据结构。

3. 本地通信代码示例

服务器端代码(server.cpp)

cpp 复制代码
#include <common_base/fdbus.h>
#include <iostream>

class MyServer : public CBaseServer
{
public:
    MyServer(const char *name) : CBaseServer(name) {}

protected:
    void onOnline(FdbSessionId_t sid, bool is_first) override
    {
        std::cout << "Client connected: " << sid << std::endl;
    }

    void onOffline(FdbSessionId_t sid, bool is_last) override
    {
        std::cout << "Client disconnected: " << sid << std::endl;
    }

    void onInvoke(CBaseJob::Ptr &msg_ref) override
    {
        std::cout << "Received message from client." << std::endl;
        CFdbMessage *msg = msg_ref.get();
        msg->reply();
    }
};

int main(int argc, char **argv){
    FDB_CONTEXT->start();
    MyServer server("MyServer");

    // 绑定到实际的IP地址和端口
    server.bind("fdbus://192.168.1.100:9001/my_server"); // 替换为服务器的实际IP地址

    server.enable();

    std::cout << "Server started. Waiting for clients..." << std::endl;
    FDB_CONTEXT->run();
    return 0;
}

客户端代码(server.cpp)

cpp 复制代码
#include <common_base/fdbus.h>
#include <iostream>

class MyClient : public CBaseClient
{
public:
    MyClient(const char *name) : CBaseClient(name) {}

protected:
    void onOnline(FdbSessionId_t sid, bool is_first) override
    {
        std::cout << "Connected to server: " << sid << std::endl;
        CFdbMessage *msg = new CFdbMessage();
        invoke(msg, 0, "Hello, Server!");
    }

    void onOffline(FdbSessionId_t sid, bool is_last) override
    {
        std::cout << "Disconnected from server: " << sid << std::endl;
    }

    void onReply(CBaseJob::Ptr &msg_ref) override
    {
        std::cout << "Received reply from server." << std::endl;
    }
};

int main(int argc, char **argv)
{
    FDB_CONTEXT->start();
    MyClient client("MyClient");

    // 连接到实际的IP地址和端口
    client.connect("fdbus://192.168.1.100:9001/my_server"); // 替换为服务器的实际IP地址

    std::cout << "Client started. Connecting to server..." << std::endl;
    FDB_CONTEXT->run();
    return 0;
}

上层应用可以利用FDBus提供的消息传递机制进行通信。应用可以创建自己的消息类型,通过FDBus的invokereplybroadcast方法进行消息传递。

相关推荐
问道飞鱼4 小时前
分布式中间件-Pika一个高效的分布式缓存组件
分布式·缓存·中间件
开MINI的工科男6 小时前
深蓝学院-- 量产自动驾驶中的规划控制算法 小鹏
人工智能·机器学习·自动驾驶
懒洋洋的华36910 小时前
消息队列-Kafka(概念篇)
分布式·中间件·kafka
nfgo17 小时前
Apollo自动驾驶项目(二:cyber框架分析)
人工智能·自动驾驶·unix
机械心1 天前
最优化理论与自动驾驶(十一):基于iLQR的自动驾驶轨迹跟踪算法(c++和python版本)
人工智能·机器学习·自动驾驶
happycao1231 天前
kafka 一步步探究消费者组与分区分配策略
中间件·kafka
酒饮微醉-1 天前
论文阅读--Planning-oriented Autonomous Driving(一)
论文阅读·笔记·学习·自动驾驶
问道飞鱼2 天前
分布式中间件-redis相关概念介绍
redis·分布式·中间件
苹果酱05672 天前
使用 React Testing Library 测试自定义 React Hooks
java·开发语言·spring boot·后端·中间件
没有名字的小羊2 天前
fastjson漏洞
运维·网络·web安全·中间件