使用fastdds替换原有协议为protobuf

proto定义

bash 复制代码
syntax = "proto3";

package example;

message MyMessage {
  int32 id = 1;
  string content = 2;
}

pub端

cpp 复制代码
#include <iostream>
#include <fastdds/dds/domain/DomainParticipantFactory.hpp>
#include <fastdds/dds/domain/DomainParticipant.hpp>
#include <fastdds/dds/topic/Topic.hpp>
#include <fastdds/dds/publisher/Publisher.hpp>
#include <fastdds/dds/publisher/DataWriter.hpp>
#include <fastdds/dds/publisher/qos/PublisherQos.hpp>
#include <fastdds/dds/publisher/qos/DataWriterQos.hpp>
#include <fastdds/dds/topic/TypeSupport.hpp>
#include "example.pb.h"

using namespace eprosima::fastdds::dds;

class ProtobufType : public TopicDataType {
public:
	ProtobufType() {
		setName("example::MyMessage");
		m_typeSize = 4 + 100; // Adjust size accordingly
		m_isGetKeyDefined = false;
	}

	bool serialize(void* data, eprosima::fastrtps::rtps::SerializedPayload_t* payload) override {
		example::MyMessage* message = static_cast<example::MyMessage*>(data);
		std::string serializedMessage;
		message->SerializeToString(&serializedMessage);
		payload->length = static_cast<uint32_t>(serializedMessage.size());
		memcpy(payload->data, serializedMessage.data(), payload->length);
		return true;
	}

	bool deserialize(eprosima::fastrtps::rtps::SerializedPayload_t* payload, void* data) override {
		example::MyMessage* message = static_cast<example::MyMessage*>(data);
		std::string serializedMessage(reinterpret_cast<char*>(payload->data), payload->length);
		return message->ParseFromString(serializedMessage);
	}

	std::function<uint32_t()> getSerializedSizeProvider(void* data) override {
		return [data]() -> uint32_t {
			example::MyMessage* message = static_cast<example::MyMessage*>(data);
			return static_cast<uint32_t>(message->ByteSizeLong());
		};
	}

	void* createData() override {
		return new example::MyMessage();
	}

	void deleteData(void* data) override {
		delete static_cast<example::MyMessage*>(data);
	}

	bool getKey(void* data, InstanceHandle_t* ihandle, bool force_md5 = false) override {
		return false;
	}
};

int main() {
	// 创建DomainParticipant
	DomainParticipantQos participantQos;
	DomainParticipant* participant = DomainParticipantFactory::get_instance()->create_participant(0, participantQos);

	if (participant == nullptr) {
		std::cerr << "创建DomainParticipant失败!" << std::endl;
		return 1;
	}

	// 注册类型
	TypeSupport myType(new ProtobufType());
	myType.register_type(participant);

	// 创建Topic
	TopicQos topicQos;
	Topic* topic = participant->create_topic("MyTopic", "example::MyMessage", topicQos);

	if (topic == nullptr) {
		std::cerr << "创建Topic失败!" << std::endl;
		return 1;
	}

	// 创建Publisher
	PublisherQos publisherQos;
	Publisher* publisher = participant->create_publisher(publisherQos);

	if (publisher == nullptr) {
		std::cerr << "创建Publisher失败!" << std::endl;
		return 1;
	}

	// 创建DataWriter
	DataWriterQos writerQos;
	DataWriter* writer = publisher->create_datawriter(topic, writerQos);

	if (writer == nullptr) {
		std::cerr << "创建DataWriter失败!" << std::endl;
		return 1;
	}
	std::this_thread::sleep_for(std::chrono::seconds(1));
	// 创建Protobuf消息
	example::MyMessage message;
	message.set_id(1);
	message.set_content("123");

	// 发布消息
	writer->write(&message);

	// 清理资源
	participant->delete_contained_entities();
	DomainParticipantFactory::get_instance()->delete_participant(participant);

	return 0;
}

SUB端

cpp 复制代码
#include <iostream>
#include <thread>
#include <chrono>
#include <fastdds/dds/domain/DomainParticipantFactory.hpp>
#include <fastdds/dds/domain/DomainParticipant.hpp>
#include <fastdds/dds/topic/Topic.hpp>
#include <fastdds/dds/subscriber/Subscriber.hpp>
#include <fastdds/dds/subscriber/DataReader.hpp>
#include <fastdds/dds/subscriber/qos/SubscriberQos.hpp>
#include <fastdds/dds/subscriber/qos/DataReaderQos.hpp>
#include <fastdds/dds/subscriber/SampleInfo.hpp>
#include <fastdds/dds/topic/TypeSupport.hpp>
#include "example.pb.h"

using namespace eprosima::fastdds::dds;

class MyListener : public DataReaderListener {
	void on_data_available(DataReader* reader) override {
		example::MyMessage serializedMessage;
		SampleInfo info;

		// 读取数据
		if (reader->take_next_sample(&serializedMessage, &info) == ReturnCode_t::RETCODE_OK) {
			if (info.valid_data) {

				// 打印消息
				std::cout << "Received message: id=" << serializedMessage.id() << ", content=" << serializedMessage.content() << std::endl;
			}
		}
	}
};

class ProtobufType : public TopicDataType {
public:
	ProtobufType() {
		setName("example::MyMessage");
		m_typeSize = 4 + 100; // Adjust size accordingly
		m_isGetKeyDefined = false;
	}

	bool serialize(void* data, eprosima::fastrtps::rtps::SerializedPayload_t* payload) override {
		example::MyMessage* message = static_cast<example::MyMessage*>(data);
		std::string serializedMessage;
		message->SerializeToString(&serializedMessage);
		payload->length = static_cast<uint32_t>(serializedMessage.size());
		memcpy(payload->data, serializedMessage.data(), payload->length);
		return true;
	}

	bool deserialize(eprosima::fastrtps::rtps::SerializedPayload_t* payload, void* data) override {
		example::MyMessage* message = static_cast<example::MyMessage*>(data);
		std::string serializedMessage(reinterpret_cast<char*>(payload->data), payload->length-1);
		return message->ParseFromString(serializedMessage);
	}
	std::function<uint32_t()> getSerializedSizeProvider(void* data) override {
		return [data]() -> uint32_t {
			example::MyMessage* message = static_cast<example::MyMessage*>(data);
			return static_cast<uint32_t>(message->ByteSizeLong());
		};
	}

	void* createData() override {
		return new example::MyMessage();
	}

	void deleteData(void* data) override {
		delete static_cast<example::MyMessage*>(data);
	}

	bool getKey(void* data, eprosima::fastrtps::rtps::InstanceHandle_t* ihandle, bool force_md5 = false) override {
		// 对于此示例,我们假设不需要键(即,我们不使用基于键的过滤)  
		//*ihandle = eprosima::fastrtps::rtps::c_InstanceHandle_Unknown();
		return false;
	}

};

int main() {
	// 创建DomainParticipant
	DomainParticipantQos participantQos;
	DomainParticipant* participant = DomainParticipantFactory::get_instance()->create_participant(0, participantQos);

	if (participant == nullptr) {
		std::cerr << "创建DomainParticipant失败!" << std::endl;
		return 1;
	}

	// 注册类型
	TypeSupport myType(new ProtobufType());
	myType.register_type(participant);

	// 创建Topic
	TopicQos topicQos;
	Topic* topic = participant->create_topic("MyTopic", "example::MyMessage", topicQos);

	if (topic == nullptr) {
		std::cerr << "创建Topic失败!" << std::endl;
		return 1;
	}

	// 创建Subscriber
	SubscriberQos subscriberQos;
	Subscriber* subscriber = participant->create_subscriber(subscriberQos);

	if (subscriber == nullptr) {
		std::cerr << "创建Subscriber失败!" << std::endl;
		return 1;
	}

	// 创建DataReader
	DataReaderQos readerQos;
	DataReader* reader = subscriber->create_datareader(topic, readerQos, new MyListener());

	if (reader == nullptr) {
		std::cerr << "创建DataReader失败!" << std::endl;
		return 1;
	}

	// 等待接收消息
	std::cout << "Waiting for messages..." << std::endl;
	std::this_thread::sleep_for(std::chrono::minutes(100));

	// 清理资源
	participant->delete_contained_entities();
	DomainParticipantFactory::get_instance()->delete_participant(participant);

	return 0;
}
相关推荐
earthzhang20212 小时前
【1028】字符菱形
c语言·开发语言·数据结构·c++·算法·青少年编程
AA陈超4 小时前
虚幻引擎5 GAS开发俯视角RPG游戏 P05-08 UI 部件数据表
c++·游戏·ue5·游戏引擎·虚幻
纵有疾風起5 小时前
C++——类和对象(3)
开发语言·c++·经验分享·开源
承渊政道6 小时前
动态内存管理
c语言·c++·经验分享·c#·visual studio
孤独得猿7 小时前
聊天室项目开发——etcd的安装和使用
linux·服务器·c++·etcd
new coder7 小时前
[c++语法学习]Day10:c++引用
开发语言·c++·学习
哼?~8 小时前
C++11标准 上 (万字解析)
开发语言·c++
给大佬递杯卡布奇诺8 小时前
FFmpeg 基本API avformat_alloc_context 函数内部调用流程分析
c++·ffmpeg·音视频
楼田莉子8 小时前
C++学习:C++11扩展:constexpr特性
开发语言·c++·学习
eurotruck8 小时前
c++贪吃蛇V1.0
开发语言·c++·贪吃蛇