【通信中间件】Fdbus HelloWorld实例

Fdbus实例教程

Fdbus简介

Fdbus 全称 Fast Distributed Bus(高速分布式总线),提供IPC+RPC功能。适用于多种OS:

  • Linux
  • QNX
  • AnroidOS
  • Window

Fdbus本质是Socket,IPC基于Unix domain socket,RPC基于TCP。使用Google Protobuf进行序列化和反序列化。

利用它,可以实现同域间的IPC通信,比如应用和OS间。也可以实现跨域、跨设备间通信,比如不同设备间数据传输,比如host/gust间的数据传输。
在这里插入图片描述

Fdbus的一些特点

  • 支持多种通信模式,比如点对点、注册/发布、广播等等。
  • 支持服务动态发现,自带心跳检测、重连,上线通知、离线检测等功能。
  • 支持一定程度的安全策略配置,token、证书、访问鉴权等等。
  • 支持Log调试,可以通过调试工具抓取在Fdbus上传输的内容。

其作者jeremy_cz(膜拜大神)对于FDBus的介绍非常详细。本文就不介绍了。关于FDBUS的内容,可以阅读作者的《Fast Distributed Bus - FDBus:高速分布式总线以及中间件开发框架》

Fdbus实例教程

基于Fdbus在一台Linux上,写一个C/S通信的Hellworld(例子)。
PC OS:Ubutun 20.04

编译Fdbus
  • 编译protobuf
git clone https://github.com/protocolbuffers/protobuf.git
git submodule update --init --recursive
mkdir -p build
cd build
# 这里把/usr作为了安装目录 
cmake -DCMAKE_INSTALL_PREFIX=/usr -DBUILD_SHARED_LIBS=1 ../cmake
make -j4
make install
  • 编译fdbus

git clone https://gitee.com/jeremyczhen/fdbus.git
cd fdbus
mkdir -p build/install
cd build
cmake -DCMAKE_INSTALL_PREFIX=install -Dfdbus_LOG_TO_STDOUT ../cmake
make -j4

编译成功后,会在build目录下生成大概以下文件,其中name_server是FDBUS用来管理服务名的进程,一会跑test需要运行它(具体请查看Fdbus作者jeremy_cz的博客)。编译生成内容大概如下

CMakeCache.txt
CMakeFiles
cmake_install.cmake
cmake_uninstall.cmake
fdbclienttest
fdbservertest
fdbxclient
fdbxserver
host_server
libfdbus-clib.so
libfdbus.so
logsvc
logviewer
lsclt
lsdp
lsevt
lshost
lssvc
Makefile
name_server
ntfcenter
HellWorld

这里直接在fdbus/example中新建了HelloWorld目录,目录结构(主要为了方便,直接借用fdbus源码的cmake。使用其他方式也可以,只要引用fdbus的lib和头文件即可。)

HelloWorld
-- HelloClient.cpp
-- HelloServer.cpp
-- HelloWorld.pb.h
-- HelloWorld.pb.cc
-- HelloWorld.proto

其中HelloWorld.pb.cc和HelloWorld.pb.h,是通过HelloWorld.proto生成的。生成命令

protoc --proto_path=. --cpp_out=. HelloWorld.proto
  • HelloWorld.proto
syntax = "proto2";message HelloWorld
{required string name = 1; 
}
  • HelloServer.cpp
#define FDB_LOG_TAG "HELLO_SERVER"
#include <fdbus/fdbus.h>
#include "HelloWorld.pb.h"
#include <fdbus/CFdbProtoMsgBuilder.h>
#include <fdbus/cJSON/cJSON.h>
#include <fdbus/CFdbCJsonMsgBuilder.h>using namespace ipc::fdbus;
// FDBUS提供的功能线程
static CBaseWorker main_worker;static const int METHOD_ID = 1;class HelloServer : public CBaseServer
{
public:HelloServer(const char*name, CBaseWorker* work = 0): CBaseServer(name, work){// Empty}protected:void onOnline(const CFdbOnlineInfo &info){std::cout << "connected to the client" << std::endl;}void onOffline(const CFdbOnlineInfo &info){std::cout << "disconnected from client" << std::endl;}/* called when client calls invoke() */void onInvoke(CBaseJob::Ptr &msg_ref){auto msg = castToMessage<CBaseMessage *>(msg_ref);static int32_t elapse_time = 0;switch (msg->code()){case METHOD_ID:{HelloWorld client;CFdbProtoMsgParser parser(client);if (!msg->deserialize(parser)){return;}std::cout << "Client name " << client.name() << std::endl;/* fill in protocol buffer and reply to client */HelloWorld server;server.set_name("Linduo");CFdbProtoMsgBuilder builder(server);msg->reply(msg_ref, builder);}break;default:break;}}
};int main(int argc, char*argv[])
{
/* start fdbus context thread */FDB_CONTEXT->start();fdbLogAppendLineEnd(true);FDB_CONTEXT->registerNsWatchdogListener([](const tNsWatchdogList &dropped_list){for (auto it = dropped_list.begin(); it != dropped_list.end(); ++it){printf("Error!!! Endpoint drops - name: %s, pid: %d\n",it->mClientName.c_str(), it->mPid);}});CBaseWorker *worker_ptr = &main_worker;/* start worker thread */worker_ptr->start();/* create servers and bind the address: svc://service_name */for (int i = 1; i < argc; ++i){std::string server_name = argv[i];std::string url(FDB_URL_SVC);url += server_name;server_name += "_server";auto server = new HelloServer(server_name.c_str(), worker_ptr);server->enableWatchdog(true);server->enableUDP(true);server->setExportableLevel(FDB_EXPORTABLE_SITE);server->bind(url.c_str());}// 将主线程变为WorkThreadCBaseWorker background_worker;background_worker.start(FDB_WORKER_EXE_IN_PLACE);
}
  • HelloClient.cpp
#define FDB_LOG_TAG "HELLO_SERVER"
#include <fdbus/fdbus.h>
#include "HelloWorld.pb.h"
#include <fdbus/CFdbProtoMsgBuilder.h>
#include <fdbus/cJSON/cJSON.h>
#include <fdbus/CFdbCJsonMsgBuilder.h>using namespace ipc::fdbus;
// FDBUS提供的功能线程
static CBaseWorker main_worker;static const int METHOD_ID = 1;class HelloServer : public CBaseServer
{
public:HelloServer(const char*name, CBaseWorker* work = 0): CBaseServer(name, work){// Empty}protected:void onOnline(const CFdbOnlineInfo &info){std::cout << "connected to the client" << std::endl;}void onOffline(const CFdbOnlineInfo &info){std::cout << "disconnected from client" << std::endl;}/* called when client calls invoke() */void onInvoke(CBaseJob::Ptr &msg_ref){auto msg = castToMessage<CBaseMessage *>(msg_ref);static int32_t elapse_time = 0;switch (msg->code()){case METHOD_ID:{HelloWorld client;CFdbProtoMsgParser parser(client);if (!msg->deserialize(parser)){return;}std::cout << "Client name " << client.name() << std::endl;/* fill in protocol buffer and reply to client */HelloWorld server;server.set_name("Linduo");CFdbProtoMsgBuilder builder(server);msg->reply(msg_ref, builder);}break;default:break;}}
};int main(int argc, char*argv[])
{/* start fdbus context thread */FDB_CONTEXT->start();fdbLogAppendLineEnd(true);FDB_CONTEXT->registerNsWatchdogListener([](const tNsWatchdogList &dropped_list){for (auto it = dropped_list.begin(); it != dropped_list.end(); ++it){printf("Error!!! Endpoint drops - name: %s, pid: %d\n",it->mClientName.c_str(), it->mPid);}});CBaseWorker *worker_ptr = &main_worker;/* start worker thread */worker_ptr->start();/* create servers and bind the address: svc://service_name */for (int i = 1; i < argc; ++i){std::string server_name = argv[i];std::string url(FDB_URL_SVC);url += server_name;server_name += "_server";auto server = new HelloServer(server_name.c_str(), worker_ptr);server->enableWatchdog(true);server->enableUDP(true);server->setExportableLevel(FDB_EXPORTABLE_SITE);server->bind(url.c_str());}// 将主线程变为WorkThreadCBaseWorker background_worker;background_worker.start(FDB_WORKER_EXE_IN_PLACE);
}
  • 编译部分:加到了dbus/cmake/pb-example/example.cmake中,在cmake中编译上面的cpp
add_executable(helloworldclient${PACKAGE_SOURCE_ROOT}/example/HelloWorld/HelloClient.cpp${PACKAGE_SOURCE_ROOT}/example/HelloWorld/HelloWorld.pb.cc${PACKAGE_SOURCE_ROOT}/example/HelloWorld/HelloWorld.pb.h
)add_executable(helloworldserver${PACKAGE_SOURCE_ROOT}/example/HelloWorld/HelloServer.cpp${PACKAGE_SOURCE_ROOT}/example/HelloWorld/HelloWorld.pb.cc${PACKAGE_SOURCE_ROOT}/example/HelloWorld/HelloWorld.pb.h
)
  • 在fdbus/cmake/CMakeLists.txt中引入了这个cmake,并且加入了C++14的Flag。
if (MSVC)add_definitions("-D__WIN32__")
elseif(fdbus_ANDROID)add_definitions("-D__LINUX__")
else()if(CMAKE_COMPILER_IS_GNUCXX)set(CMAKE_CXX_FLAGS "-std=gnu++14 -Wall -Wl,--copy-dt-needed-entries ${CMAKE_CXX_FLAGS}")endif()#add_compile_options(-g -O0)add_definitions("-D__LINUX__")
endif()include(pb-example/example.cmake)
  • 重新运行cmake,然后make。编译出helloworldclient和helloworldserver两个文件。
cmake -DCMAKE_INSTALL_PREFIX=install -Dfdbus_LOG_TO_STDOUT ../cmake
make -j4
运行HelloWorld
  • 开三个终端,分别运行,无先后顺序。Server/Client运行无需先后顺序,这点也是Fdbus的有点。大概原理是,通过服务动态绑定,当网络中的Server上线时,Client会自动连接该Service。
# 开3个终端,分别运行。其中name_server(用来实现服务动态绑定)
./name_server
./helloworldserver my
./helloworldclient my

执行成功后:
helloworldserver会输出从客户端收到的内容。

connected to the client
Client name Adver

helloworldclient会输出从服务端收到的内容。

connected to the server
Server name Linduo

PS:name_server在服务端和客户端连接时,不是必须得。如果两端指定了IPC端口,可以不使用name_server连接。但是不使用name_server时,就需要控制好连接时序。所以一般来讲,应用时都是启动一个name_server。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/6101.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MathType打开的窗口太多 MathType说打开窗口太多无法复制怎么解决

在数学文档编辑中&#xff0c;MathType作为一款常用的数学公式编辑工具&#xff0c;使用过程中&#xff0c;我们常常会遇到一些问题&#xff0c;比如MathType打开的窗口过多导致软件运行缓慢甚至崩溃&#xff0c;以及在复制过程中出现“打开窗口太多&#xff0c;无法复制”的提…

241 基于matlab的Dijkstra算法进行路径规划

基于matlab的Dijkstra算法进行路径规划。可根据实际情况输入障碍物和起止点坐标信息&#xff1b; 输出避碰最短路径&#xff1b; 能够利用切线图算法对障碍物区域进行环境建模&#xff0c;设置障碍物的位置和区域。利用Dijkstra算法进行路径规划。程序已调通&#xff0c;可直接…

细说SVPWM原理及软件实现原理,关联PWM实现

细说SVPWM原理及软件实现原理&#xff0c;关联PWM实现 文章目录 细说SVPWM原理及软件实现原理&#xff0c;关联PWM实现1. 前言2. 基础控制原理回顾2.1 FOC 原理回顾2.2 细说 SVPWM2.2.1 矢量扇区计算2.2.2 矢量作用时间计算 2.2.3 如何理解 U4 U6 2/3Udc?2.2.4 如何理解 U4m…

文件传送协议

壹、文件传输协议FTP 一、FTP简介 文件传送协议FTP曾是互联网上使用最广泛的协议&#xff1b; 在互联网发展的早期阶段&#xff0c;用FTP传送文件约占整个互联网的通信量的三分之一&#xff1b;知道1995年&#xff0c;www的通信量才首次超过FTP。 FTP实现的是通过网络实现异…

GaussDB数据库事务管理

一、引言 事务管理是数据库系统中至关重要的一部分&#xff0c;它确保了数据库的一致性和可靠性。在GaussDB数据库中&#xff0c;事务管理不仅遵循传统的ACID特性&#xff0c;还提供了一些高级功能。本文将深入探讨GaussDB数据库事务管理的各个方面。 二、事务的基本概念 2.1…

机器学习:深入解析SVM的核心概念【四、软间隔与正则化】

软间隔与正则化 问题一&#xff1a;优化目标函数是如何得到的&#xff1f;得到的过程是怎样的&#xff1f;问题二&#xff1a;拉格朗日乘子法计算详细过程问题三&#xff1a;KKT条件求解过程问题四&#xff1a;结构风险最小化&#xff08;SRM&#xff09;的原理 在前面的讨论中…

Rust Turbofish 的由来

0x01 什么是 Turbofish 我们运行如下 Rust Snippet&#xff1a; fn main() {let numbers: Vec<i32> vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10];let even_numbers numbers.into_iter().filter(|n| n % 2 0).collect();println!("{:?}", even_numbers); }不出意…

Android 设置头像 - 相册拍照

Android开发在个人信息管理中&#xff0c;如果设置头像&#xff0c;一般都提供了从相册选择和拍照两种方式。下午将针对设置用户头像相册和拍照两种方式的具体实现进行详细说明。 在实际实现过程中需要使用到权限管理&#xff0c;新版本的Android需要动态申请权限&#xff0c;权…

React Context

Context https://juejin.cn/post/7244838033454727227?searchId202404012120436CD549D66BBD6C542177 context 提供了一个无需为每层组件手动添加 props, 就能在组件树间进行数据传递的方法 React 中数据通过 props 属性自上而下(由父及子)进行传递&#xff0c;但此种用法对…

Matlab|二阶锥松弛在配电网最优潮流计算中的应用

目录 一、主要内容 二、部分代码 三、程序代码 四、下载链接 一、主要内容 最优潮流计算是电网规划、优化运行的重要基础。首先建立了配电网全天有功损耗最小化的最优潮流计算模型&#xff1b;其次结合辐射型配电网潮流特点建立支路潮流约束&#xff0c;并考虑配电网中的可…

macOS sonoma 14.4.1编译JDK 12

macOS sonoma 14.4.1编译JDK 12 环境参考文档开始简述问题心路历程着手解决最终解决(前面有点啰嗦了&#xff0c;可以直接看这里) 记录一次靠自己看代码解决问题的经历(总之就是非常开心)。 首先&#xff0c;先diss一下bing&#xff0c;我差一点就放弃了。 环境 macOS sonom…

[力扣]——125.验证回文串

class Solution {public static boolean isValidChar(char ch){if((ch > a && ch < z) ||(ch > 0 && ch < 9)){return true;}return false;}public boolean isPalindrome(String s) {// 将大小写统一起来s s.toLowerCase();int left 0, right s…

vulnhub靶场之FunBox-2

一.环境搭建 1.靶场描述 Boot2Root ! This can be a real life scenario if rockies becomes admins. Easy going in round about 15 mins. Bit more, if you are find and stuck in the rabbit-hole first. This VM is created/tested with Virtualbox. Maybe it works with…

百面算法工程师 | 支持向量机——SVM

文章目录 15.1 SVM15.2 SVM原理15.3 SVM解决问题的类型15.4 核函数的作用以及特点15.5 核函数的表达式15.6 SVM为什么引入对偶问题15.7 SVM使用SGD及步骤15.8 为什么SVM对缺失数据敏感15.9 SVM怎么防止过拟合 欢迎大家订阅我的专栏一起学习共同进步 祝大家早日拿到offer&#x…

利用亚马逊云科技GenAI企业助手Amazon Q Business构建企业代码开发知识库

2024年五一节假日的前一天&#xff0c;亚马逊云科技正式重磅发布了云计算行业期待已久的服务——Amazon Q Business。Amazon Q Business是专为企业用户打造的一个开箱即用的完善而强大企业GenAI助手。企业用户只需要将Amazon Q Business连接到现有的企业内部数据源&#xff0c;…

小程序地理位置接口权限直接抄作业

小程序地理位置接口有什么功能&#xff1f; 随着小程序生态的发展&#xff0c;越来越多的小程序开发者会通过官方提供的自带接口来给用户提供便捷的服务。但是当涉及到地理位置接口时&#xff0c;却经常遇到申请驳回的问题&#xff0c;反复修改也无法通过&#xff0c;给的理由也…

【自研网关系列】过滤器链 -- 限流过滤器

&#x1f308;Yu-Gateway&#xff1a;&#xff1a;基于 Netty 构建的自研 API 网关&#xff0c;采用 Java 原生实现&#xff0c;整合 Nacos 作为注册配置中心。其设计目标是为微服务架构提供高性能、可扩展的统一入口和基础设施&#xff0c;承载请求路由、安全控制、流量治理等…

ESP32-C3模组上跑通MQTT(1)

本文内容参考&#xff1a; 《ESP32-C3 物联网工程开发实战》 特此致谢&#xff01; 一、远程控制的介绍 什么是远程控制&#xff1f;顾名思义&#xff0c;远程控制就是远距离控制&#xff0c;是指控制设备&#xff08;如智能手机、计算机等网络设备&#xff09;通过广域网控制…

FIFO Generate IP核使用——FIFO写操作详解及Status Flags页配置

本文介绍了FIFO的写操作及Status Flags页的配置信息。 1 FIFO 写入操作 当FIFO的写入使能&#xff08;write enable&#xff09;被置位&#xff0c;并且FIFO未满时&#xff0c;数据会从输入总线&#xff08;din&#xff09;被添加到FIFO中&#xff0c;并且写入确认&#xff0…

Mac环境下ollama部署和体验

欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码)&#xff1a;https://github.com/zq2599/blog_demos 关于ollama ollama和LLM&#xff08;大型语言模型&#xff09;的关系&#xff0c;类似于docker和镜像&#xff0c;可以在ollama服务中管理和运行各种LLM&…