Zinx框架-游戏服务器开发002:按照三层结构模式重构代码功能-待续

news2024/11/29 12:33:20

文章目录

  • 1 Zinx框架总览
  • 2 三层模式的分析
  • 3 三层重构原有的功能 - 头文件
    • 3.1 通道层Stdin和Stdout类
      • 3.1.2 StdInChannel
      • 3.1.2 StdOutChannel
    • 3.2 协议层CmdCheck和CmdMsg类
      • 3.2.1 CmdCheck单例模式
        • 3.2.1.1 单例模式
        • 3.2.1.2 * 命令识别类向业务层不同类别做分发
      • 3.2.2 CmdMsg自定义用户信息类,继承UserData
    • 3.3 业务层:回显类, 输出通道控制类, 日期前缀管理类
      • 3.3.1 回显对象EchoRole
      • 3.3.2 控制输入输出
      • 3.3.3 日期管理类

1 Zinx框架总览

在这里插入图片描述

2 三层模式的分析

在这里插入图片描述

3 三层重构原有的功能 - 头文件

三层结构重构原有功能

  1. 自定义消息类,继承UserData,添加一个成员变量szUserData
  2. 定义多个Role类继承Irole,重写ProcMsg函数,进行不同处理
  3. 定义protocol类,继承Iprotocol,重写四个函数,两个函数时原始
    数据和用户数据之间的转换;另两个用来找消息处理对象和消息发
    送对象。
  4. 定义channel类,继承Ichannel,在getnextinputstage函数中返回协
    议对象

3.1 通道层Stdin和Stdout类

通道类,派生自基础处理者类,提供基于系统调用的数据收发功能
一般地,用户应该根据处理的文件(信息源)不同而创建通道类的子类或选用合适的实用类(已经提供的通道类子类)来完成系统级文件IO
在这里插入图片描述

class StdInChannel :
	public Ichannel
{
public:
	StdInChannel();
	virtual ~StdInChannel();

	// 通过 Ichannel 继承
	virtual bool Init() override;
	virtual bool ReadFd(std::string& _input) override;
	virtual bool WriteFd(std::string& _output) override;
	virtual void Fini() override;
	virtual int GetFd() override;
	virtual std::string GetChannelInfo() override;
	virtual AZinxHandler* GetInputNextStage(BytesMsg& _oInput) override;
};

class StdOutChannel :public Ichannel
{
	// 通过 Ichannel 继承
	virtual bool Init() override;
	virtual bool ReadFd(std::string& _input) override;
	virtual bool WriteFd(std::string& _output) override;
	virtual void Fini() override;
	virtual int GetFd() override;
	virtual std::string GetChannelInfo() override;
	virtual AZinxHandler* GetInputNextStage(BytesMsg& _oInput) override;
};

3.1.2 StdInChannel

bool StdInChannel::ReadFd(std::string& _input)
{
	cin >> _input;
	return true;
}

bool StdInChannel::WriteFd(std::string& _output)
{
	return false;
}

int StdInChannel::GetFd()
{
	return 0;
}

std::string StdInChannel::GetChannelInfo()
{
	return "stdin";
}

AZinxHandler* StdInChannel::GetInputNextStage(BytesMsg& _oInput)
{
	/*返回协议对象*/
	return CmdCheck::GetInstance();
}

3.1.2 StdOutChannel

bool StdOutChannel::ReadFd(std::string& _input)
{
	return false;
}

bool StdOutChannel::WriteFd(std::string& _output)
{
	cout << _output << endl;
	return true;
}

int StdOutChannel::GetFd()
{
	return 1;
}

std::string StdOutChannel::GetChannelInfo()
{
	return "stdout";
}

AZinxHandler* StdOutChannel::GetInputNextStage(BytesMsg& _oInput)
{
	return nullptr;
}

3.2 协议层CmdCheck和CmdMsg类

3.2.1 CmdCheck单例模式

  1. 原始数据和业务数据相互函数,开发者重写该函数,实现协议
  2. 获取处理角色对象函数,开发者应该重写该函数,用来指定当前产生的用户数据消
  3. 获取发送通道函数,开发者应该重写该函数,用来指定当前字节流应该由哪个通道对象发出
class CmdCheck :
	public Iprotocol
{
	CmdCheck();
	virtual ~CmdCheck();
	static CmdCheck *poSingle;
public:
	// 通过 Iprotocol 继承
	/*原始数据和业务数据相互函数,开发者重写该函数,实现协议*/
	virtual UserData * raw2request(std::string _szInput) override;
	virtual std::string * response2raw(UserData & _oUserData) override;
	/*获取处理角色对象函数,开发者应该重写该函数,用来指定当前产生的用户数据消息应该传递给哪个角色处理*/
	virtual Irole * GetMsgProcessor(UserDataMsg & _oUserDataMsg) override;
    /*获取发送通道函数,开发者应该重写该函数,用来指定当前字节流应该由哪个通道对象发出*/
	virtual Ichannel * GetMsgSender(BytesMsg & _oBytes) override;
	static CmdCheck *GetInstance() {
		return poSingle;
	}
	std::string szOutChannel;
};
3.2.1.1 单例模式

构造全局唯一的协议对象

#include "CmdCheck.h"
#include "CmdMsg.h"
#include "EchoRole.h"
using namespace std;

CmdCheck *CmdCheck::poSingle = new CmdCheck();

3.2.1.2 * 命令识别类向业务层不同类别做分发

通过是不是命令来进行区分:if (isCmd)

Irole * CmdCheck::GetMsgProcessor(UserDataMsg & _oUserDataMsg)
{
	szOutChannel = _oUserDataMsg.szInfo;
	if ("stdin" == szOutChannel)
	{
		szOutChannel = "stdout";
	}
	/*根据命令不同,交给不同的处理role对象*/
	auto rolelist = ZinxKernel::Zinx_GetAllRole();

	auto pCmdMsg = dynamic_cast<CmdMsg *>(_oUserDataMsg.poUserData);

	/*读取当前消息是否是命令*/
	bool isCmd = pCmdMsg->isCmd;

	Irole *pRetRole = NULL;

	for (Irole *prole : rolelist)
	{
		if (isCmd)
		{
			auto pOutCtrl = dynamic_cast<OutputCtrl *>(prole);
			if (NULL != pOutCtrl)
			{
				pRetRole = pOutCtrl;
				break;
			}
		}
		else
		{
			auto pDate = dynamic_cast<DatePreRole *>(prole);
			if (NULL != pDate)
			{
				pRetRole = pDate;
				break;
			}
		}
	}
	
	return pRetRole;
}

3.2.2 CmdMsg自定义用户信息类,继承UserData

class CmdMsg :
	public UserData
{
public:
	/*成员变量表示要回显的字符串*/
	std::string szUserData;
	/*开启输出标志*/
	bool isOpen = true;
	/*该消息是命令*/
	bool isCmd = false;
	/*要加前缀*/
	bool needDatePre = false;
	
	CmdMsg();
	virtual ~CmdMsg();
};

3.3 业务层:回显类, 输出通道控制类, 日期前缀管理类

3.3.1 回显对象EchoRole

主要有init, procmsg,fini三个函数

#pragma once
#include <zinx.h>

class EchoRole :
	public Irole
{
public:
	EchoRole();
	virtual ~EchoRole();

	// 通过 Irole 继承
	virtual bool Init() override;
	virtual UserData * ProcMsg(UserData & _poUserData) override;
	virtual void Fini() override;
};
  • 容易出错的点:参数一必须是一个堆对象
UserData * EchoRole::ProcMsg(UserData & _poUserData)
{
	/*写出去*/
	GET_REF2DATA(CmdMsg, input, _poUserData);
	CmdMsg *pout = new CmdMsg(input);
	ZinxKernel::Zinx_SendOut(*pout, *(CmdCheck::GetInstance()));
	return nullptr;
}

3.3.2 控制输入输出

  1. 写一个关闭输出的角色类,摘除输出通道或添加输出通道
  2. 在CmdMsg用户数据类中添加开关标志,是否是命令标志
  3. 在协议类中,根据输入字符串,设置开关标志和是否是命令的标志
  4. 在协议类分发消息时,判断是否是命令,是命令则发给关闭输出角 色类,否则发给回显角色类
class OutputCtrl :public Irole {
	// 通过 Irole 继承
	virtual bool Init() override;
	virtual UserData * ProcMsg(UserData & _poUserData) override;
	virtual void Fini() override;
	Ichannel *pOut = NULL;
};

3.3.3 日期管理类

class DatePreRole :public Irole {
	// 通过 Irole 继承
	virtual bool Init() override;
	virtual UserData * ProcMsg(UserData & _poUserData) override;
	virtual void Fini() override;
	bool needAdd = false;
};

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

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

相关文章

Python+pandas将Excel文件xlsx批量转换xls(代码全注释)

文章目录 专栏导读背景安装的库代码部分(全注释)视频演示总结&#x1f44d; 该系列文章专栏&#xff1a;[Python办公自动化专栏]PS: xls转xlsx文章在这&#xff1a;【点我直达】 专栏导读 &#x1f338; 欢迎来到Python办公自动化专栏—Python处理办公问题&#xff0c;解放您的…

MySQL缩短查询时间小技巧

背景 今天我要统计数据表的最新更新时间&#xff0c;有些表数据量特别大&#xff0c;所以统计比较费时间&#xff0c;但是如果使用一下小技巧&#xff0c;就会极大加快查询时间&#xff0c;适合小白的调优手段。 查询更新时间 select max(update_time) from test大概表的行数…

外汇天眼:账户惨遭冻结?一招帮你解决问题!

在外汇交易中&#xff0c;难免会出现大大小小的问题&#xff0c;其中账户被冻结也是经常能够见到的。首先摒弃外汇黑平台&#xff0c;在正规的外汇平台&#xff0c;如果出现账户被冻结的问题&#xff0c;可能是以下几种原因&#xff1a; 第一种是使用平台禁止的辅助软件进行薅…

python-opencv写入视频文件无法播放

python-opencv写入视频文件无法播放 在采用Python写OpenCV的视频时&#xff0c;生成的视频总是无法播放&#xff0c;大小只有不到两百k&#xff0c;播放器提示视频已经损坏。网上搜了一些方法&#xff0c;记录下解决办法。 代码如下 fourcc cv2.VideoWriter_fourcc(*MJPG) fp…

CRM客户关系管理系统源码 PHP客户管理系统源码

CRM客户关系管理系统源码 PHP客户管理系统源码 系统采用&#xff1a;PHPMYSQL 开发&#xff0c;功能完善&#xff0c;界面美观。 功能介绍&#xff1a; 1.客户管理&#xff1a;客户列表、今日新增客户、近7天新增客户、本月新增客户、新增客户&#xff08;包括客户名称、所在…

青柚课堂|为3960余名学生解惑青春期

2023年10月30日-11月1日&#xff0c;益阳市海棠学校邀请益阳市蚂蚁社会工作服务中心的儿童性教育公益讲师们开展了以“我们的青春期”为主题的“青柚课堂”性教育公益讲座&#xff0c;授课初中部班级72个&#xff0c;受益青少年3960余人。 在热身游戏的活跃氛围中&#xff0c;讲…

投标之---信用中国查询信用

https://www.creditchina.gov.cn/ 挨个点 &#xff0c;有的需要跳转网页&#xff0c;输入企业信息就是可以的&#xff0c;具体按照招标要求&#xff0c;如果没有具体的&#xff0c;那就是多查询几个

【Python3】【力扣题】225. 用队列实现栈

【力扣题】题目描述&#xff1a; 栈&#xff1a;线性集合。后进先出。 队列&#xff1a;线性集合。先进先出。也有双端队列和循环队列。 【Python3】代码&#xff1a; 1、解题思路&#xff1a;两个队列。队列1存储元素&#xff0c;队列2辅助。元素从队尾进入队列2&#xff0c;…

身份证二要素核验API:提高身份验证的精确性与效率

前言 在数字时代&#xff0c;身份验证已经成为各行各业的重要环节。无论是金融交易、电子商务还是在线服务&#xff0c;确保用户身份的准确性至关重要。身份证二要素核验API&#xff0c;作为一种先进的技术解决方案&#xff0c;正在逐渐崭露头角&#xff0c;为身份验证带来了精…

springboot中使用redis管理session

前言 使用软件&#xff1a; redis&#xff1a; linux版本下载 windows版本下载 安装redis 下载redis http://download.redis.io/releases/ 源码安装redis&#xff08;ubuntu&#xff09; #将指定版本的redis上传到服务器#解压 sudo tar -xzvf redis-6.2.4.tar.gzcd re…

家用小型洗衣机哪款性价比高?公认好用四款内衣洗衣机推荐

小型的内衣洗衣机由于体积小巧&#xff0c;而且实用&#xff0c;非常适合没有太多空闲时间的上班族以及小型住户的使用。想要挑选到一款能够满足每日清洗需要&#xff0c;同时拥有便携与高效率的小型内衣洗衣机&#xff0c;也许会让你选择得有些烦恼。我们为大家挑选了一些性价…

仿真建模工具:AnyLogic 8.8.5 Crack

多方法建模环境&#xff0c;使用所有三种现代模拟方法开发模型&#xff1a; 系统动力学 这三种方法可以任意组合使用&#xff0c;通过一种软件来模拟任何复杂性的业务系统。在 AnyLogic 中&#xff0c;您可以使用各种可视化建模语言&#xff1a;流程图、状态图、动作图以及库存…

数据结构与算法之美学习笔记:14 | 排序优化:如何实现一个通用的、高性能的排序函数?

目录 前言如何选择合适的排序算法&#xff1f;如何优化快速排序&#xff1f;举例分析排序函数 前言 本节课程思维导图&#xff1a; 几乎所有的编程语言都会提供排序函数&#xff0c;比如 C 语言中 qsort()&#xff0c;C STL 中的 sort()、stable_sort()&#xff0c;还有 Java …

游戏中的-雪花算法

1、什么是雪花算法&#xff1f; 雪花算法&#xff08;Snowflake&#xff09;是一种生成唯一ID的算法。在游戏开发过程中会为玩家生成唯一的id&#xff0c;或者玩家获得一件装备&#xff0c;为这件装备生成唯一的Id&#xff0c;将此角色和装备的Id保存于数据库当中。 全局唯一性…

Spring-AOP-面向切面编程

文章目录 目录 文章目录 前言 一 . 场景设定和问题复现 二 . 解决技术[代理模式] 2.1 代理模式 2.2 静态代理 2.3 动态代理 三 . 面向切面编程思想(AOP) 3.1 面向切面编程思想 3.2 AOP 思想的应用场景 3.3 AOP术语名词介绍 3.3.1 横切关注点 3.3.2 通知(增强) 3…

面试算法52:展平二叉搜索树

题目 给定一棵二叉搜索树&#xff0c;请调整节点的指针使每个节点都没有左子节点。调整之后的树看起来像一个链表&#xff0c;但仍然是二叉搜索树。 分析 看起来需要按照节点的值递增的顺序遍历二叉搜索树中的每个节点&#xff0c;并将节点用指向右子节点的指针连接起来。这…

观测云产品更新 | 单点登录新增 OIDC / Oauth2.0 协议、数据转发优化、场景优化等

观测云更新 数据转发 1. 新增【观测云】选项&#xff0c;支持将数据保存到观测云的对象存储&#xff0c;计费逻辑按天出账&#xff0c;每天统计存储的压缩后的数据大小&#xff0c;按照每 GB 0.007 元出具对应账单。 2. 数据转发菜单导航位置调整至【管理】模块&#xff0c;…

ActiveMQ是什么?-九五小庞

MQ是消息中间件&#xff0c;是一种在分布式系统中应用程序借以传递消息的媒介&#xff0c;常用的有ActiveMQ&#xff0c;RabbitMQ&#xff0c;kafka。ActiveMQ是Apache下的开源项目&#xff0c;完全支持JMS1.1和J2EE1.4规范的JMS Provider实现。特点&#xff1a;1、支持多种语言…

黑色星期五来袭,Ozon为你提供丰富的推广工具和资源,助你实现销售突破!

Ozon的“黑色星期五”促销活动为卖家们提供了丰富的推广工具和资源&#xff0c;以确保他们的商品在促销期间获得最大的曝光度和销售额。卖家们应该充分利用这些机会&#xff0c;制定合适的折扣策略&#xff0c;并确保他们的商品在Ozon平台上脱颖而出。 为了推广Ozon黑色星期五促…

AI、万圣节与聊斋;用AI写甜蜜恋爱小暖文;AGI新趋势与机会洞察;Meta官方Llama 2入门指南 | ShowMeAI日报

&#x1f440;日报&周刊合集 | &#x1f3a1;生产力工具与行业应用大全 | &#x1f9e1; 点赞关注评论拜托啦&#xff01; &#x1f440; 时代杂志评选2023年度最佳发明&#xff0c;AI赛道入选名单 https://time.com/collection/best-inventions-2023 10 月 24 日&#xff…