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

本文主要是介绍Zinx框架-游戏服务器开发002:按照三层结构模式重构代码功能-待续,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 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;
};

这篇关于Zinx框架-游戏服务器开发002:按照三层结构模式重构代码功能-待续的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/338781

相关文章

服务器集群同步时间手记

1.时间服务器配置(必须root用户) (1)检查ntp是否安装 [root@node1 桌面]# rpm -qa|grep ntpntp-4.2.6p5-10.el6.centos.x86_64fontpackages-filesystem-1.41-1.1.el6.noarchntpdate-4.2.6p5-10.el6.centos.x86_64 (2)修改ntp配置文件 [r

这15个Vue指令,让你的项目开发爽到爆

1. V-Hotkey 仓库地址: github.com/Dafrok/v-ho… Demo: 戳这里 https://dafrok.github.io/v-hotkey 安装: npm install --save v-hotkey 这个指令可以给组件绑定一个或多个快捷键。你想要通过按下 Escape 键后隐藏某个组件,按住 Control 和回车键再显示它吗?小菜一碟: <template

Hadoop企业开发案例调优场景

需求 (1)需求:从1G数据中,统计每个单词出现次数。服务器3台,每台配置4G内存,4核CPU,4线程。 (2)需求分析: 1G / 128m = 8个MapTask;1个ReduceTask;1个mrAppMaster 平均每个节点运行10个 / 3台 ≈ 3个任务(4    3    3) HDFS参数调优 (1)修改:hadoop-env.sh export HDFS_NAMENOD

嵌入式QT开发:构建高效智能的嵌入式系统

摘要: 本文深入探讨了嵌入式 QT 相关的各个方面。从 QT 框架的基础架构和核心概念出发,详细阐述了其在嵌入式环境中的优势与特点。文中分析了嵌入式 QT 的开发环境搭建过程,包括交叉编译工具链的配置等关键步骤。进一步探讨了嵌入式 QT 的界面设计与开发,涵盖了从基本控件的使用到复杂界面布局的构建。同时也深入研究了信号与槽机制在嵌入式系统中的应用,以及嵌入式 QT 与硬件设备的交互,包括输入输出设

OpenHarmony鸿蒙开发( Beta5.0)无感配网详解

1、简介 无感配网是指在设备联网过程中无需输入热点相关账号信息,即可快速实现设备配网,是一种兼顾高效性、可靠性和安全性的配网方式。 2、配网原理 2.1 通信原理 手机和智能设备之间的信息传递,利用特有的NAN协议实现。利用手机和智能设备之间的WiFi 感知订阅、发布能力,实现了数字管家应用和设备之间的发现。在完成设备间的认证和响应后,即可发送相关配网数据。同时还支持与常规Sof

C++11第三弹:lambda表达式 | 新的类功能 | 模板的可变参数

🌈个人主页: 南桥几晴秋 🌈C++专栏: 南桥谈C++ 🌈C语言专栏: C语言学习系列 🌈Linux学习专栏: 南桥谈Linux 🌈数据结构学习专栏: 数据结构杂谈 🌈数据库学习专栏: 南桥谈MySQL 🌈Qt学习专栏: 南桥谈Qt 🌈菜鸡代码练习: 练习随想记录 🌈git学习: 南桥谈Git 🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈�

活用c4d官方开发文档查询代码

当你问AI助手比如豆包,如何用python禁止掉xpresso标签时候,它会提示到 这时候要用到两个东西。https://developers.maxon.net/论坛搜索和开发文档 比如这里我就在官方找到正确的id描述 然后我就把参数标签换过来

让树莓派智能语音助手实现定时提醒功能

最初的时候是想直接在rasa 的chatbot上实现,因为rasa本身是带有remindschedule模块的。不过经过一番折腾后,忽然发现,chatbot上实现的定时,语音助手不一定会有响应。因为,我目前语音助手的代码设置了长时间无应答会结束对话,这样一来,chatbot定时提醒的触发就不会被语音助手获悉。那怎么让语音助手也具有定时提醒功能呢? 我最后选择的方法是用threading.Time

在JS中的设计模式的单例模式、策略模式、代理模式、原型模式浅讲

1. 单例模式(Singleton Pattern) 确保一个类只有一个实例,并提供一个全局访问点。 示例代码: class Singleton {constructor() {if (Singleton.instance) {return Singleton.instance;}Singleton.instance = this;this.data = [];}addData(value)

usaco 1.3 Mixing Milk (结构体排序 qsort) and hdu 2020(sort)

到了这题学会了结构体排序 于是回去修改了 1.2 milking cows 的算法~ 结构体排序核心: 1.结构体定义 struct Milk{int price;int milks;}milk[5000]; 2.自定义的比较函数,若返回值为正,qsort 函数判定a>b ;为负,a<b;为0,a==b; int milkcmp(const void *va,c