asio2和工程模式的使用

news/2024/12/28 0:29:12/文章来源:https://www.cnblogs.com/wuhaiqiong/p/18629031

以下是基于工厂模式的设计和实现,分为三部分:Link 类RTA 类工厂类


Link 是一个封装底层通信逻辑的类,支持发送、接收、以及广播功能。

#include <asio2/udp/udp_server.hpp>
#include <string>
#include <functional>
#include <memory>class Link {
public:using RecvCallback = std::function<void(const std::string& data, const std::string& clientAddress, uint16_t clientPort)>;Link() : server_() {// 设置广播选项server_.bind_init([this]() {asio2::error_code ec;server_.acceptor().set_option(asio::socket_base::broadcast(true), ec);if (ec) {std::cerr << "Failed to enable broadcast: " << ec.message() << std::endl;}});}// 启动通信void start(const std::string& host, const std::string& port) {server_.bind_recv([this](std::shared_ptr<asio2::udp_session>& session_ptr, std::string_view data) {if (recvCallback_) {recvCallback_(std::string(data), session_ptr->remote_address(), session_ptr->remote_port());}});if (!server_.start(host, port, asio2::use_kcp)) {std::cerr << "Failed to start Link: " << asio2::last_error_msg() << std::endl;} else {std::cout << "Link started on " << host << ":" << port << std::endl;}}// 停止通信void stop() {server_.stop();}// 设置接收数据的回调函数void setRecvCallback(RecvCallback callback) {recvCallback_ = std::move(callback);}// 广播数据void broadcast(const std::string& data, const std::string& broadcastAddress, const std::string& port) {server_.async_send_to(data, broadcastAddress, port, [](asio2::error_code ec, std::size_t bytes_sent) {if (ec) {std::cerr << "Broadcast failed: " << ec.message() << std::endl;} else {std::cout << "Broadcast success: " << bytes_sent << " bytes sent" << std::endl;}});}// 发送数据给指定的客户端void sendTo(const std::string& data, const std::string& clientAddress, const std::string& port) {server_.async_send_to(data, clientAddress, port, [](asio2::error_code ec, std::size_t bytes_sent) {if (ec) {std::cerr << "Send failed: " << ec.message() << std::endl;}});}private:asio2::udp_server server_;RecvCallback recvCallback_; // 数据接收回调
};

2. RTA 类

RTA 类依赖于 Link,用来完成具体的业务逻辑。Link 是通过依赖注入的方式传入的。

#include <iostream>
#include <memory>
#include <string>class RTA {
public:explicit RTA(std::shared_ptr<Link> link) : link_(std::move(link)) {// 设置接收数据的回调link_->setRecvCallback([this](const std::string& data, const std::string& clientAddress, uint16_t clientPort) {this->onReceive(data, clientAddress, clientPort);});}// 启动 RTA 的功能void start(const std::string& host, const std::string& port) {link_->start(host, port);}// 停止 RTA 的功能void stop() {link_->stop();}// 业务逻辑:处理接收到的数据void onReceive(const std::string& data, const std::string& clientAddress, uint16_t clientPort) {std::cout << "RTA received data: " << data << " from " << clientAddress << ":" << clientPort << std::endl;// 示例:发送回显数据link_->sendTo("Echo: " + data, clientAddress, std::to_string(clientPort));}private:std::shared_ptr<Link> link_; // 底层通信 Link
};

3. 工厂类

工厂类负责创建 LinkRTA 对象,并确保它们之间的依赖关系。

#include <memory>class Factory {
public:// 创建 Link 对象static std::shared_ptr<Link> createLink() {return std::make_shared<Link>();}// 创建 RTA 对象static std::unique_ptr<RTA> createRTA(std::shared_ptr<Link> link) {return std::make_unique<RTA>(std::move(link));}
};

4. 使用工厂类

以下是使用工厂类创建 LinkRTA 对象的示例:

int main() {// 通过工厂创建 Link 对象std::shared_ptr<Link> link = Factory::createLink();// 通过工厂创建 RTA 对象,并注入 Linkstd::unique_ptr<RTA> rta = Factory::createRTA(link);// 启动 RTA(同时启动底层通信 Link)rta->start("0.0.0.0", "8035");std::cout << "Press Enter to exit..." << std::endl;std::cin.get();// 停止 RTA(同时停止底层通信 Link)rta->stop();return 0;
}

5. 代码运行逻辑

  1. 工厂创建 LinkRTA

    • Link 负责底层 UDP 通信,包含发送、接收和广播功能。
    • RTA 依赖于 Link,并通过 Link 完成业务逻辑。
  2. 启动 RTA:

    • 调用 rta->start() 会启动 Link,并设置数据接收的回调。
  3. 处理接收数据:

    • Link 收到数据后,会调用注册的回调,将数据传递给 RTAonReceive 方法。
  4. 发送或广播数据:

    • RTA 使用 Link 提供的 sendTobroadcast 方法发送数据。

6. 优势

  • 模块化: Link 专注于通信逻辑,而 RTA 专注于业务逻辑。
  • 可扩展: 如果需要支持新的通信方式(如 TCP 或 WebSocket),只需扩展 Link 类,而无需修改 RTA
  • 解耦: 工厂模式将对象的创建和使用分离,方便统一管理依赖关系。

总结

通过工厂模式封装底层通信(Link)和业务逻辑(RTA),可以实现高内聚、低耦合的设计:

  • Link 提供底层通信能力,包括 UDP 收发和广播。
  • RTA 使用 Link 提供的功能来实现自己的业务逻辑。
  • 工厂类统一管理对象的创建和依赖关系。

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

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

相关文章

没有xml configuration file

点击new菜单发现没有看到XML Configuration File选项。1、正确导入spring jar包,spring5.6 maven坐标<dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>6.2.1</versi…

PostgreSQL 数据库的启动与停止管理

title: PostgreSQL 数据库的启动与停止管理 date: 2024/12/28 updated: 2024/12/28 author: cmdragon excerpt: 作为一个强大的开源关系数据库管理系统,PostgreSQL在众多应用场景中发挥着关键作用。在实际使用过程中,对于数据库的启动和停止操作至关重要。这不仅关系到数据…

人工智能Agent提示工程的六个关键要素

一个构造良好的提示封装了所有必要的信息,确保AI Agent生成准确的响应并有效地执行任务。 通过系统地组合特定组件,提示符为LLM提供了一个全面的框架,以实现最佳功能。 六个关键要素如下: 1.用户请求:这是用户提供的原始任务描述,概述了目标和期望的结果。它作为代理行为…

一个Java实现的OCR系统

一个Java实现的OCR系统 利用java17实现的一套OCR推理系统,兼容paddleocr。如下图,目前功能如下,https://github.com/jiangnanboy/JiaJiaOCR:

staticfile cdn崩了,boot cdn崩了。

背景 一天之内碰到两个cdn同时炸。 staticfile cdnboot cdn我没截图,他主站是没炸的,但是js文件访问不了,过了一段时间又好了。 后面恢复了,下面是bootcdn的速度测试,有点慢说实话。其他bootcdn太慢了,换一家用用。npmmirror 全国最nb的镜像站,无需多言。 格式如下 http…

《计算机组成及汇编语言原理》阅读笔记:p121-p122

《计算机组成及汇编语言原理》学习第 8 天,p121-p122 总结,总计 2 页。 一、技术总结 1.memory优化 (1)cache memory remove blank from "Most computers support two different kinds (levels) of cache: level one (L1) cache is built into the CPU chip itself and…

【电商系统】使用多种设计模式重构电商系统登录业务场景

一、介绍 在做业务功能开发的时候,每个程序员接触过最多的应该就是登录功能了,而一个登录功能有很多种登录交互的体现,当我们开始写登录代码的时候,前期能满足登录就行了,渐渐的系统中加入了不同业务需求的代码,以及每个登录需要特殊处理的参数,基本上我们要开发不同的接…

Android 当鸟动漫(原樱花动漫) 1.5.5.8去广告版

当鸟动漫(原樱花动漫)是许多二次元用户喜欢用的免费动漫平台,网罗了各种动漫番剧资源,新番、日漫、国漫、美漫、电影等其他内容一网打尽,应有尽有,同步更新,智能精选推荐,高清播放,自由筛选观看阅读,还支持收藏、下载、分享、反馈,好用又实用!Android 当鸟动漫:下载…

3.6背景

1.背景颜色 2.背景图片

JVM实战—3.JVM垃圾回收的算法和全流程

大纲 1.JVM内存中的对象何时会被垃圾回收 2.JVM中的垃圾回收算法及各算法的优劣 3.新生代和老年代的垃圾回收算法 4.避免本应进入S区的对象直接升入老年代 5.Stop the World问题分析 6.JVM垃圾回收的原理核心流程 7.问题汇总1.JVM内存中的对象何时会被垃圾回收 (1)什么时候会触…

adobe全家桶2025!PR PS AE下载安装教程(附赠各版本安装包)

​​Adobe作为全球知名的软件开发商,旗下包含Photoshop、Premiere、Media Encoder等多个软件系列,为数以亿计的用户提供了解决工作生活中遇到问题的办法 Adobe全家桶一键安装激活:下载地址 ​