【通信中间件】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.rhkb.cn/news/319887.html

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

相关文章

【数据结构初阶】直接插入排序

最近浅学了直接插入排序&#xff0c;写个博客做笔记&#xff01;笔记功能除外若能对读者老爷有所帮助最好不过了&#xff01; 直接插入排序是插入排序的一种&#xff0c;那么介绍直接插入排序之前先介绍一下常见的排序算法&#xff01; 目录 1.常见的排序算法 2.直接插入排…

详解LLMOps,将DevOps用于大语言模型开发

大家好&#xff0c;在机器学习领域&#xff0c;随着技术的不断发展&#xff0c;将大型语言模型&#xff08;LLMs&#xff09;集成到商业产品中已成为一种趋势&#xff0c;同时也带来了许多挑战。为了有效应对这些挑战&#xff0c;数据科学家们转向了一种新型的DevOps实践LLM-OP…

FFmpeg学习记录(四)——SDL音视频渲染实战

1.SDL使用的基本步骤 SDL Init/sDL _Quit()SDL_CreateWindow()/SDL_DestoryWindow()SDL CreateRender() SDL_Windows *windows NULL;SDL_Init(SDL_INIT_VIDEO);window SDL_CreateWindow("SDL2 Windows",200,200, 640,480,SDL_WINDOW_SHOWN);if(!window) {printf(&…

QtWindows任务栏

目录 引言任务栏进度右键菜单缩略图工具栏完整代码 引言 针对Windows系统的任务栏&#xff0c;Qt基于系统的原生接口封装有一些非常见类&#xff0c;如QWinTaskbarButton、QWinTaskbarButton、QWinThumbnailToolBar等&#xff0c;用于利用工具栏提供更多的信息&#xff0c;诸如…

C 认识指针

目录 一、取地址操作符&#xff08;&&#xff09; 二、解引用操作符&#xff08;*&#xff09; 三、指针变量 1、 指针变量的大小 2、 指针变量类型的意义 2.1 指针的解引用 2.2 指针 - 整数 2.3 调试解决疑惑 认识指针&#xff0c;指针比较害羞内敛&#xff0c;我们…

使用jdbc方式操作ClickHouse

1、创建测试表&#xff0c;和插入测试数据 create table t_order01(id UInt32,sku_id String,total_amount Decimal(16,2),create_time Datetime ) engine MergeTreepartition by toYYYYMMDD(create_time)primary key (id)order by (id,sku_id);insert into t_order01 values …

ctfshow 框架复现

文章目录 web 466web 467web 468web469web 470web 471web 472web 473web 474web 475web 476 web 466 Laravel5.4版本 &#xff0c;提交数据需要base64编码 代码审计学习—Laravel5.4 - 先知社区 (aliyun.com) 用第二条链子 反序列化格式 /admin/序列化串base64<?php na…

Flutter笔记:Widgets Easier组件库(11)- 使用提示吐丝

Flutter笔记 Widgets Easier组件库&#xff08;11&#xff09;使用提示吐丝 - 文章信息 - Author: 李俊才 (jcLee95) Visit me at CSDN: https://jclee95.blog.csdn.netMy WebSite&#xff1a;http://thispage.tech/Email: 291148484163.com. Shenzhen ChinaAddress of this …

【Java】基本程序设计结构(二)

前言&#xff1a;上一篇我们详细介绍了Java基本程序设计结构中前半部分&#xff0c;一个简单的Java应用&#xff0c;注释&#xff0c;数据类型&#xff0c;变量与常量&#xff0c;运算符&#xff0c;字符串。包括本篇将延续上篇内容介绍后续内容&#xff0c;包括输入输出&#…

「 网络安全常用术语解读 」通用配置枚举CCE详解

1. 背景介绍 NIST提供了安全内容自动化协议&#xff08;Security Content Automation Protocol&#xff0c;SCAP&#xff09;为漏洞描述和评估提供一种通用语言。SCAP组件包括&#xff1a; 通用漏洞披露(Common Vulnerabilities and Exposures, CVE)&#xff1a;提供一个描述…

2024年 Java 面试八股文——SpringCloud篇

目录 1.Spring Cloud Alibaba 中的 Nacos 是如何进行服务注册和发现的&#xff1f; 2.Spring Cloud Alibaba Sentinel 的流量控制规则有哪些&#xff1f; 3.Spring Cloud Alibaba 中如何实现分布式配置管理&#xff1f; 4.Spring Cloud Alibaba RocketMQ 的主要特点有哪些&…

2024“天一永安杯“宁波第七届网络安全大赛极安云科战队部分WP

“天一永安杯”2024 宁波第七届网络安全大赛暨第九届大学生网络技术与信息安全大赛 大赛竞赛形式 一、线上初赛 参赛人员&#xff1a;各单位自行选拔3人&#xff08;设队长1名&#xff09;组成团队&#xff0c;不足3人不允许参赛。 竞赛时间&#xff1a;8&#xff1a;30-12&…

ES集群数据备份与迁移

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、文章涉及概念讲解二、操作步骤1.创建 snapshot repository操作主机hadoop1分别操作从机hadoop2和hadoop3 2. 查看仓库信息3. 备份索引&#xff0c;生成快照…

【精品毕设推荐】基于JSP物流信息网的设计与实现

点击免费下载原文及代码、PPT 摘要 本文讲述了基于JSP物流信息网的设计与实现。该系统使用java语言开发&#xff0c;使系统具有更好的平台性和可扩展性。 该系统实现了用户登录、注册、查询快递信息、快递公司注册成为合作伙伴以及系统管理员对信息进行管理等功能。系统的主…

Android 音视频基础知识

本系列文章会介绍两个 Android NDK Demo&#xff0c;拉流端会实现一个基于 FFmpeg 的视频播放器 Demo&#xff0c;推流端会实现一个视频直播 Demo&#xff0c;当然在做 Demo 之前会介绍音视频的基础知识。以下是本系列文章的目录&#xff1a; Android 音视频基础知识 Android 音…

第二代增强-创建采购申请时的增强

文章目录 第二代增强-创建采购申请时的增强业务要求实现过程创建项目编写代码激活增强 维护消息类运行效果断点关键点另一种形式的错误提示-出口函数EXIT_SAPLMEREQ_005运行结果 第二代增强-创建采购申请时的增强 业务要求 实现过程 创建项目 编写代码 "AFNAM&#xff0c…

STM32 PWM波定时溢出中断

打开定时器和中断 主函数初始化开启PWM和中断 HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_1); __HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_1, Pwm_data); HAL_TIM_Base_Start_IT(&htim2); 回调函数中判断是否为tim2 void HAL_TIM_PeriodElapsedCallback(TIM_Han…

prometheus+grafana的安装与部署及优点

一、Prometheus 的优点 1、非常少的外部依赖&#xff0c;安装使用超简单&#xff1b; 2、已经有非常多的系统集成 例如&#xff1a;docker HAProxy Nginx JMX等等&#xff1b; 3、服务自动化发现&#xff1b; 4、直接集成到代码&#xff1b; 5、设计思想是按照分布式、微服…

【区块链】比特币架构

比特币架构 2009年1月&#xff0c;在比特币系统论文发表两个月之后&#xff0c;比特币系统正式运行并开放了源码&#xff0c;标志着比特币网络的正式诞生。通过其构建的一个公开透明、去中心化、防篡改的账本系统&#xff0c;比特币开展了一场规模空前的加密数字货币体验。在区…

Linux学习之Tcp与Udp

目录 UDP Udp协议的格式 UDP的传输特性 UDP的缓冲区 基于UDP的应用层协议 TCP协议 TCP的报文格式 1.ACK确认应答机制 2.超时重传 3.TCP的链接管理机制 为什么要三次握手呢&#xff1f; 理解TIME_WAIT状态 流量控制&#xff08;可靠性效率&#xff09; 滑动窗口 拥塞…