通用服务器系统,Engine

Engine

C++服务器编程底层库

特点

Windows,Linux双平台(Windows下为静态库,主要方便开发者调试;Linux下为动态库,用于生产环境部署)

基本包含集成服务器常用模块(数学、文件系统、配置、日志、网络、脚本、时间、多线程等)

二次开发无平台配置,无其他依赖

基于C++11开发

使用

项目使用xmake管理,使用方法详见xmake手册

注:Linux下建议使用GCC的-Wl,-rpath,.连接选项指定运行期动态连接库的优先查找目录,以方便分发部署

集成第三方说明

Zip使用miniz v2.1.0.

Lua v5.3.5.

集成Jsoncpp v1.8.4.

hiredis v0.13.3.

模块

程序模型

#include

class GameApp : public Application {

public:

GameApp() {}

virtual bool OnInit(const Commandline & cmd) override {

if (cmd.Has("--debug")) {

Logger::Instance().Initialize("game", "logs", Logger::Debug);

} else {

Logger::Instance().Initialize("game", "logs", Logger::Info);

}

/// 锁帧

LockFPS(20);

/// 填写其他初始化逻辑,当返回false时程序直接退出

return true;

}

virtual void OnBreath() override {

/// 这里填写需要每帧更新的逻辑

}

};

RUN_APP(GameApp)

网络模型

头文件socket.h,一个简单的客户端实现:

class Client : public IOListener {

public:

Client() : _socket(new Socket()) {

}

~Client() {

Close();

delete _socket;

}

bool Connect(const std::string & ip, int port) {

bool succ = _socket->Connect(ip, port);

if (succ) BindIO(_socket->ctx, IO_READ); //! 我们只需要网络有数据来时通知

return succ;

}

/// 实现数据可读时消息处理

virtual void OnReadable() override {

char buf[1024] = {0};

int readed = 0;

int recv = 0;

while (true) {

recv = _socket->Recv(buf, 1024);

if (recv > 0) {

//! TODO: process received data.

} else if (recv == 0) {

break;

} else {

Close(recv);

break;

}

}

}

void Close(int reason = 0) {

UnbindIO(); //! 关闭之前请取消IO事件监听

_socket->Close();

}

bool Send(const char * p, size_t s) {

return _socket->Send(p, s);

}

private:

Socket * _socket;

}

脚本

设计原则:Lua只负责逻辑,对象生存管理交由C++(可以注册管理到Lua)

涉及到Get操作,需要try...catch以捕获类型异常(C++注册到Lua的接口内Get不需要,调用函数不需要)

Property可以为地址方式,也可以为Getter(TG (void))、Setter(void (TS))方式注册

Method必须为int (*f)(LuaState &)

Lua不可用于多线程,只能在主线程中使用,但可以使用协程。

#include

/// 注册公共变量或函数到Lua

GLua.Register("GameSetting")//! 所有下面注册的属性或函数放在GameSetting中

.Property("nPlayerCounter", &GPlayerCount, false)//! 以地址方式注册属性,同时设置不可写

.Property("nTime", &GetTime)//! 以Getter方式注册属性,同时不注册属性的写方法(不可写)

.Method("GetAById", &GetAById);//! 注册全局Lua方法

/// 注册C++类到Lua

GLua.Register("LuaA")

.Property("nId", &A::id, false)

.Property("sName", &A::GetName, &A::SetName)

.Method("Msg", &A::SendMessage);

try {

A * p = GLua.Get("me");// 需要使用try,因为可能类型不匹配

} catch (...) {}

if (GLua.Is("me")) {} // 不需要try

GLua.Set("me", new A) // 不需要try

GLua.Call("GameSetting", "GetAById", false, 100); // 不需要try

int GetAById(LuaState & r) {

int n = r.Get(1);// 不需要try

...

}

LUA中扩展C++注册的类或名空间(注只能扩展方法,不可扩展属性)

-- 扩展名空间的方法

function XXX.yyy()

end

-- 扩展类静态方法

function LuaA.Test()

print("hehe")

end

-- 扩展类成员方法,注意:这里用的是':',因为需要使用self

function LuaA.apis:YYY()

end

内置的其他基本函数

函数

功能

print(...)

使用Logger重载的print接口[Logger::Level::Info]

print_err(...)

使用Logger重载的print接口[Logger::Level::Error]

loadbits(n, start, end) -> integer

读取一个int32中[start, end]字节表示的值

setbits(n, start, end, v) -> integer

设置一个int32中[start, end]字节表示的值

json.encode(v) -> string

将lua变量序列化成json字串

json.decode(s) -> var

将json字串反序列化成lua值

scheduler.timer(delay, func[, is_loop]) -> integer(id)

注册一个定时器

scheduler.task(hour, min, sec, func) -> integer(id)

注册一个每天hour:min:sec执行的操作

scheduler.is_valid(id) -> bool

测试一个定时器或计划是否存在

scheduler.remain(id) -> double

返回一个定时器或计划还需要多少毫秒运行

scheduler.cancel(id)

取消一个定时器或计划任务

内存池

由于本人能力有限,经实际效率测试,目前仅保留非线程安全的对象Pool(Pool.h)

Pool加锁后可用于多线程,但经测试效率还不及系统的new,但Linux下相差不大,如果考虑到无内存碎片的优点,可以自行添加。

如果采用Application的模型,Pool基本上是够用的。因为逻辑主要在主线程的Tick中触发

线程池模型

First. 编写线程内的具体工作类,继承IThreadJob.

#include

class DemoTask : public IThreadJob {

public:

DemoTask(...) { ... }//! 这里为该工作参数初始化

virtual ~DemoTask() { ... }//! 这里为工作结束时清理操作

virtual void OnRun() { ... }//! 工作的具体内容

private:

...//! 参数声明

};

Second. 创建线程池及工作对象容器

int main() {

Threads workers(4);//! 创建含有一个4个工作线程的容器

/// 增加100个并发任务(多余的会暂时等待空闲线程)

for (int i = 0; i < 100; ++i) {

workers.AddJob(...);// 传入工作需要的参数,这里自动调用 new DemoTask(...);

}

/// 等待所有的工作结束,如果不执行该操作,mgr超出生存期时会放弃未执行的任务。

workers.Wait();

return 0;

}

Redis客户端

比较简单,请自行阅读redis.h,redis.cc

定时任务

C++接口

/// 添加一个500毫秒后执行的定时器

GScheduler.Add(500, [](uint64_t id) {

printf("Timer's id : %llu", id);

});

/// 添加一个每500毫秒执行一次的定时器

GScheduler.Add(500, [](uint64_t id) {

printf("Timer's id : %llu", id);

}, true);

/// 注册每天05:00:00时执行的计划任务

GScheduler.Add(5, 0, 0, [](uint64_t id) {

printf("Task's id : %llu", id);

});

/// 是否存在定时器或计划任务

bool valid = GScheduler.IsValid(timer_id);

/// 取得一个定时器或计划多少毫秒后执行

double left = GScheduler.GetRemainTime(timer_id);

/// 取消一个定时器或计划任务

GScheduler.Cancel(timer_id);

Lua接口

scheduler.timer(500, function(id) end);

scheduler.timer(500, function(id) end, true);

scheduler.task(5, 0, 0, function(id) end);

scheduler.is_valid(timer_id);

scheduler.remain(timer_id);

scheduler.cancel(timer_id);

日志

多线程安全

日志使用之前可以初始化(不是必要的,但建议初始化—)

日志生成的结构说明

RootOfLogs指定的日志根目录

|-- 20160803首先日志会根据“年月日”分文件夹

||-- main_01_00_00.000.log其次日志会按指定大小分文件记录,文件名为指定的"Name_时_分_秒.毫秒.log"

||-- main_01_27_18.193.log

/// 初始化日志。日志名为main, 放在logs目录下,输出等级为DEBUG,每个文件最大为4M

Logger::Instance().Initialize("main", "logs", Logger::Debug, 4 * 1024 * 1024);

/// 写日志

LOG_INFO("Hello");

LOG_DEBUG("Hello %d", 2);

LOG_ERR("Error : %s", "Test");

LOG_WARN("You have a warning");

HASH

头文件 Crypto.h

CRC32算法:uint32_t CalcCRC(const char * mem, size_t size, uint32_t pre_crc = 0)

BKDRHash算法:uint32_t CalcHash(const char * mem, size_t size)

MD5算法:class MD5

SHA-1算法:class SHA1

HMAC-SHA1算法:class HMAC_SHA1

工具库

单例模型:Singleton (singleton.h)

生存域模型:ScopeGuard (scope_gurad.h)

ZIP压缩/解压缩算法:Zip(zip.h)

字符串操作:string_tools.h

配置库

CSV文件的读取见:CsvFile(csv.h)

INI文件的读取见:IniFile(ini.h)

JSON文件,使用jsoncpp:Json::Value, Json::Reader (json.h)

命令行解析: Flags (flags.h)

系统相关

头文件os.h。包含:

高精度时间:

OS::Tick()

OS::Now()

OS::GetTimeZone()

OS::ParseDataTime(year, month, day, hour, min, sec)

文件系统:

OS::Exists(path)

OS::CreateDir(dir)

OS::GetCWD()

OS::SetCWD(path)

OS::GetFullPath(path)

OS::GetDirName(path)

OS::GetFileName(path)

OS::GetFiles(path, recursive)

创建GUID/uuid

OS::CreateID();

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
智慧校园建设方案旨在通过融合先进技术,如物联网、大数据、人工智能等,实现校园的智能化管理与服务。政策的推动和技术的成熟为智慧校园的发展提供了基础。该方案强调了数据的重要性,提出通过数据的整合、开放和共享,构建产学研资用联动的服务体系,以促进校园的精细化治理。 智慧校园的核心建设任务包括数据标准体系和应用标准体系的建设,以及信息化安全与等级保护的实施。方案提出了一站式服务大厅和移动校园的概念,通过整合校内外资源,实现资源共享平台和产教融合就业平台的建设。此外,校园大脑的构建是实现智慧校园的关键,它涉及到数据中心化、数据资产化和数据业务化,以数据驱动业务自动化和智能化。 技术应用方面,方案提出了物联网平台、5G网络、人工智能平台等新技术的融合应用,以打造多场景融合的智慧校园大脑。这包括智慧教室、智慧实验室、智慧图书馆、智慧党建等多领域的智能化应用,旨在提升教学、科研、管理和服务的效率和质量。 在实施层面,智慧校园建设需要统筹规划和分步实施,确保项目的可行性和有效性。方案提出了主题梳理、场景梳理和数据梳理的方法,以及现有技术支持和项目分级的考虑,以指导智慧校园的建设。 最后,智慧校园建设的成功依赖于开放、协同和融合的组织建设。通过战略咨询、分步实施、生态建设和短板补充,可以构建符合学校特色的生态链,实现智慧校园的长远发展。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值