十一、实现逻辑层

news2024/11/22 17:47:03

        系列文章目录:C++ asio网络编程-CSDN博客 

1、服务器架构设计

2、单例模板类

        我们的LogicSystem类为单例类,可以只把这个类写为单例,也可以写一个单例模板类,让其它类继承它就可以形成单例。这里选择第二种,因为后面可能还会实现其他的单例类。

#pragma once
#include <memory>
#include <mutex>
#include <iostream>

template <typename T>
class Singleton
{
public:
	~Singleton() {
		std::cout << "singleton destruct" << std::endl;
	}

	static std::shared_ptr<T> getInstance() {
		static std::once_flag s_flag;
		std::call_once(s_flag, [&]() {
			_instance = std::shared_ptr<T>(new T);
		});
		return _instance;
	}

	void printAddress() {
		std::cout << _instance->get() << std::endl;
	}


protected:
	Singleton() = default;
	Singleton(const Singleton<T>&) = delete;
	Singleton& operator = (const Singleton<T>& st) = delete;

	static std::shared_ptr<T> _instance;
};

template <typename T>
std::shared_ptr<T> Singleton<T>::_instance = nullptr;

        C++基础好的同学应该很容易看明白,有不明白的地方可以利用一些ai工具解读一下,也很简单。

3、LogicSystem类

#pragma once
#include "Singleton.h"
#include <queue>
#include <thread>
#include "const.h"
#include "Session.h"
#include <map>
#include <functional>
#include <json/json.h>
#include <json/value.h>
#include <json/reader.h>

class LogicNode;
class Session;

typedef std::function<void(std::shared_ptr<Session>, const short& msg_id, const std::string& msg_data)> FunCallBack;

class LogicSystem : public Singleton<LogicSystem>
{
	friend class Singleton<LogicSystem>;

public:
	~LogicSystem();

	void postMsgToQue(std::shared_ptr<LogicNode> msg);

private:
	LogicSystem();
	void registerCallBacks();
	void helloWordCallBack(std::shared_ptr<Session>, const short& msg_id, const std::string& msg_data);
	void dealMsg();

	std::queue<std::shared_ptr<LogicNode>> _msg_que;  // 逻辑队列
	std::mutex _mutex;
	std::condition_variable _consume; // 条件变量,控制当逻辑队列为空时保证线程暂时挂起等待,不要干扰其他线程
	std::thread _worker_thread;
	bool _b_stop;  // 停止信号,控制逻辑类中止工作线程
	std::map<short, FunCallBack> _fun_callback; // 回调函数的map,根据id查找对应的逻辑处理函数
};

#include "LogicSystem.h"

LogicSystem::~LogicSystem()
{
	_b_stop = true;
	_consume.notify_one();
	_worker_thread.join();
}

void LogicSystem::postMsgToQue(std::shared_ptr<LogicNode> msg)
{
	std::unique_lock<std::mutex> ulock(_mutex);
	_msg_que.push(msg);

	if (_msg_que.size() == 1) {
		_consume.notify_one();
	}
}

LogicSystem::LogicSystem() : _b_stop(false)
{
	registerCallBacks();
	_worker_thread = std::thread(&LogicSystem::dealMsg, this);
}

void LogicSystem::registerCallBacks()
{
	_fun_callback[MSG_HELLO_WORD] = std::bind(&LogicSystem::helloWordCallBack, this,
		std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);
}

void LogicSystem::helloWordCallBack(std::shared_ptr<Session> session, const short& msg_id, const std::string& msg_data)
{
	Json::Reader reader;
	Json::Value root;
	reader.parse(msg_data, root);
	std::cout << "receive msg id is " << root["id"].asInt() << "msg data is " 
		<< root["data"].asString() << std::endl;
	root["data"] = "server has receive msg: " + root["data"].asString();

	std::string return_str = root.toStyledString();
	session->send(return_str, root["id"].asInt());
}

void LogicSystem::dealMsg()
{
	for (;;) {
		std::unique_lock<std::mutex> ulock(_mutex);
		// 队列为空并且正在处理消息则用条件变量等待
		while (_msg_que.empty() && !_b_stop) {
			_consume.wait(ulock);  // 先释放资源再解锁
		}
		// 关闭状态时,取出逻辑队列所有数据及时处理,并且退出循环
		if (_b_stop) {
			while (!_msg_que.empty()) {
				auto msg_node = _msg_que.front();
				std::cout << "receive msg id: " << msg_node->_recvNode->_msg_id << std::endl;
				auto call_back_iter = _fun_callback.find(msg_node->_recvNode->_msg_id);
				if (call_back_iter == _fun_callback.end()) {
					_msg_que.pop();
					continue;
				}
				call_back_iter->second(msg_node->_session, 
					msg_node->_recvNode->_msg_id, 
					std::string(msg_node->_recvNode->_data, msg_node->_recvNode->_cur_len));
				_msg_que.pop();
			}
			break;
		}
		// 没有停服,并且队列有数据
		auto msg_node = _msg_que.front();
		std::cout << "receive msg id: " << msg_node->_recvNode->_msg_id << std::endl;
		auto call_back_iter = _fun_callback.find(msg_node->_recvNode->_msg_id);
		if (call_back_iter == _fun_callback.end()) {
			_msg_que.pop();
			continue;
		}
		call_back_iter->second(msg_node->_session,
			msg_node->_recvNode->_msg_id,
			std::string(msg_node->_recvNode->_data, msg_node->_recvNode->_cur_len));
		_msg_que.pop();
	}
}

        MSG_HELLO_WORD定义在const.h中,表示消息id

enum MSG_IDS {
	MSG_HELLO_WORD = 1001
};

4、逻辑节点

        在Session.h中,我们可以添加一个逻辑节点类

class LogicNode
{
	friend class LogicSystem;
public:
    // 第二个参数是为了防止session被提前释放
	LogicNode(std::shared_ptr<Session>, std::shared_ptr<RecvNode>); 
private:
	std::shared_ptr<Session> _session;
	std::shared_ptr<RecvNode> _recvNode;
};
LogicNode::LogicNode(std::shared_ptr<Session> session, std::shared_ptr<RecvNode> recvNode)
	: _session(session), _recvNode(recvNode)
{
}

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

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

相关文章

Python利用openpyxl复制Excel文件且保留样式—另存为副本(附完整代码)

目录 专栏导读库的介绍库的安装前言结果预览目录结构完整代码总结专栏导读 🌸 欢迎来到Python办公自动化专栏—Python处理办公问题,解放您的双手 🏳️‍🌈 博客主页:请点击——> 一晌小贪欢的博客主页求关注 👍 该系列文章专栏:请点击——>Python办公自动化专…

配电房动环监控系统 温湿度环境、供配电、UPS集中管控@卓振思众

在现代电力网络中&#xff0c;配电房作为供电系统的核心节点&#xff0c;承担着至关重要的角色。为了保障电力供应的稳定性与可靠性&#xff0c;配电房的管理与监控显得尤为重要。随着技术的不断进步&#xff0c;【卓振思众】智能的配电房动环监控系统应运而生&#xff0c;成为…

# Spring Cloud Alibaba Nacos_配置中心与服务发现(四)

Spring Cloud Alibaba Nacos_配置中心与服务发现&#xff08;四&#xff09; 一、Nacos 配置管理-集群部署 1、 把 nacos 应用程序包&#xff0c;复制3份&#xff0c;分别命名为 nacos1, nacos2, nacos3 分别在 conf 目录下&#xff0c;修改 application.properties 配置文件…

【大模型LLMs】LLMs-based Summarization研究进展梳理

【大模型LLMs】LLMs-based Summarization方法梳理 Survey1 Knowledge Distillation from LLMsRefereeInheritSumm 2 Prompt Engineering2.1 Template EngineeringOdSum 2.2 CoTSumCoTCoDSuReSliSumRefiner 梳理基于大模型的摘要总结方案&#xff0c;持续汇总中&#xff08;更关…

数据埋点系列 9|数据伦理与隐私-在合规与创新间寻找平衡

在数据驱动决策的时代&#xff0c;数据伦理和隐私保护已成为至关重要的议题。组织必须在利用数据创新和保护用户隐私之间找到平衡。本文将探讨数据伦理的核心原则、隐私保护的技术实现&#xff0c;以及如何在合规和创新之间取得平衡。 目录 1. 数据伦理的核心原则1.1 透明度1…

【机器学习】卷积神经网络简介

&#x1f308;个人主页: 鑫宝Code &#x1f525;热门专栏: 闲话杂谈&#xff5c; 炫酷HTML | JavaScript基础 ​&#x1f4ab;个人格言: "如无必要&#xff0c;勿增实体" 文章目录 卷积神经网络简介1. 引言2. CNN的基本概念2.1 什么是卷积神经网络2.2 CNN与传统…

uniprot数据库转换ID功能

1.登入uniprot数据库 uniprot 2. 选择ID mapping&#xff0c;输入P31946和P62258等uniprot数据库中的蛋白质ID 然后在To database选项中选择&#xff1a;sequence databases---RefSeq Protein---map 显示已完成&#xff0c;点击ID MAPPING 下方的网址&#xff0c;则可以看到uni…

「12月·长沙」第三届传感、测量、通信和物联网技术国际会议(SMC-IoT 2024)

第三届传感、测量、通信和物联网技术国际会议&#xff08;SMC-IoT 2024&#xff09;将于2024年11月29日-2024年12月1日召开&#xff0c;由湖南涉外经济学院主办。会议中发表的文章将会被收录, 并于见刊后提交EI核心索引。 会议旨在围绕传感、测量、通信和物联网技术等相关研究…

mysql数据库 行级锁,间隙锁和临键锁详解

目录 准备 查看锁命令 演示 普通的select语句 共享锁与排他锁 无索引行锁升级为表锁 间隙锁&临键锁 索引上的等值查询(索引为唯一索引) 索引上的等值查询(索引为普通索引) 索引上的范围查询(唯一索引) 准备 我的mysql版本是8。 CREATE TABLE user (id int unsi…

.NET 8 跨平台高性能边缘采集网关

目录 前言 项目介绍 通道 插件 设备 变量 项目特点 可视化操作 脚本支持 自定义插件支持 性能 断线缓存 完整可商用的边缘网关 项目插件 采集插件 业务插件 项目展示 1、ThingsGateway 演示地址 2、登录页面 3、系统首页 4、网关管理 5、网关状态 6、网关…

【区块链+金融服务】基于区块链的一站式绿色金融开放平台 | FISCO BCOS应用案例

科技的进步为绿色金融发展提供了新的机遇&#xff0c;但银行、企业、第三方金融机构等在进行绿色金融业务操作过程中&#xff0c; 存在着相关系统和服务平台建设成本高、迭代难度大、数据交互弱、适配难等痛点。 基于此&#xff0c;中碳绿信采用国产开源联盟链底层平台 FISCO …

Element-01.快速入门

1.什么是Element 2.快速入门 第二步引入ElementUI组件库&#xff0c;在当前的工程目录下的main.js文件中引入。 import Vue from vue; import ElementUI from element-ui; import element-ui/lib/theme-chalk/index.css; import App from ./App.vue;Vue.use(ElementUI); 第一…

Heckman 模型及 Stata 具体操作步骤

目录 一、文献综述 二、理论原理 三、实证模型 四、稳健性检验 五、程序代码及解释 六、代码运行结果 一、文献综述 Heckman 模型自提出以来&#xff0c;在众多领域得到了广泛且深入的应用。例如&#xff0c;在劳动经济学领域&#xff0c;Heckman&#xff08;1979&#xf…

CSS小玩意儿:霓虹灯卡片

一&#xff0c;效果 二&#xff0c;代码 1&#xff0c;搭个框架 主题是一个圆角矩形&#xff0c;其中有垂直、水平居中的文字。 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>霓虹灯卡片 - 步骤1…

区块链技术在Facebook中的潜力:未来趋势与挑战

数据安全的新高度 区块链技术以其去中心化和不可篡改的特性&#xff0c;正在成为提升数据安全和隐私保护的重要工具。Facebook作为全球最大的社交媒体平台之一&#xff0c;正积极探索如何将区块链技术应用于其平台&#xff0c;以增强用户数据的安全性和隐私保护。Facebook在应…

数字化营销在公域场景中的无限可能

在如今的商业领域&#xff0c;公域场景为企业提供了广阔的发展空间&#xff0c;而数字化营销则成为了企业在这些场景中脱颖而出的关键利器。 ​ 一、电商平台营销 当企业在淘宝、京东等大型电商平台开设店铺&#xff0c;数字化营销便开始大显身手。 企业不仅能踊跃参与像双十…

新华三H3CNE网络工程师认证—OSPF基础

OSPF是N1&#xff08;初级&#xff09;阶段比较重要的知识点&#xff0c;路由协议当中非常重要的一个知识点。 文章目录 一、常用的三大路由协议二、静态路由的问题1、无法适应规模较大的网络2、 无法动态响应网络变化 三、动态路由协议分类1、按工作区域分类2、按工作机制及算…

manim官方文档 _ 快速入门板块 _ 汉化 | 辅助快速理解manim功能

注 &#xff1a; 在此之前&#xff0c;请按照安装中的步骤安装 Manim 并确保其正常运行。有关在 Jupyterlab 或 Jupyter notebook 中使用 Manim 的信息&#xff0c;请参阅 IPython magic command的文档。 文章目录 概述实例一 &#xff1a;绘制一个圆形1、启动新项目 let s go2…

美股动荡,散户逆势抄底!科技股成香饽饽

最近&#xff0c;美股市场可不太平&#xff0c;各大指数纷纷下跌。面对这样的行情&#xff0c;不少投资者都有些慌了。但你知道吗&#xff1f;有一群人却在此时看到了机会&#xff0c;他们就是散户投资者&#xff01; 逆势操作&#xff0c;散户“抄底” 8月份&#xff0c;美股…

SpringBoot整合定时任务@Scheduled

SpringBoot自带的定时任务非常简单操作&#xff0c;其实就是一个Scheduled注解。 第一步&#xff1a;创建类&#xff0c;定义执行定时任务的方法 package com.oracle.springboottimer.timer;import org.springframework.scheduling.annotation.Scheduled; import org.springfr…