C++服务开发入门指南
  • 序言
  • 前言
  • 一、一个简单的服务
    • 1 什么是服务
    • 2 服务可以用来做什么
    • 3 简单服务框架
  • 二、网络通信服务框架
    • 1 网络服务的基本概念
    • 2 增加监听端口
    • 3 处理客户端会话
    • 小结
  • 三、添加基础模块
    • 1 日志模块
    • 2 定时器
    • 3 事件机制
    • 4 线程池
    • 5 线程安全
    • 小结
  • 四、一个聊天服务
    • 1 需求描述及分析
    • 2 概要设计
    • 3 创建服务项目
    • 4 ClientUser实现
    • 5 RoomMgr实现
    • 6 ChatRoom实现
    • 7 RoomIDMgr实现
    • 小结
  • 五、测试、迭代及重构
    • 1 测试
    • 2 迭代
    • 3 重构
    • 4 版本号
  • 六、架构设计
    • 1 单点服务
    • 2 分布式服务
  • 七、部署及发布
    • 1 部署环境
    • 2 编译环境
    • 3 部署服务
    • 4 发布服务
  • 八、线上问题处理
    • 1 线上问题
    • 2 问题处理
  • 九、程序员的职业规划
    • 职业规划
Powered by GitBook
On this page
  • 1、导出基类库
  • 2、创建一个新项目
  1. 四、一个聊天服务

3 创建服务项目

1、导出基类库

之前的服务框架是以可执行程序的方式实现的,现在需要导出lib库。

修改框架项目的CMakeLists.txt文件中的导出配置

#add_executable(SimpleService ${SRC_LIST})
add_library(ServiceBase STATIC ${SRC_LIST})

编译文件,得到libServiceBase.a,放到lib文件夹。

将相应的头文件导出到include文件夹。

2、创建一个新项目

新创建一个项目,起名为ChatService,用来实现聊天服务项目。

首先编写整个服务的入口main.cpp

#include "ChatService.h"

int main(){
    ChatService svr;
    svr.Start();
    return 0;
}

入口是一个简单的main函数,包含ChatService.h头文件,函数主题创建了一个聊天服务,执行服务的Start() 方法,后面的工作就交给服务类了。

#pragma once
#include "NetService.h"
#include "RoomMgr.h"

class ClientUser;
class ChatService :
    public CNetService
{
public:
    ChatService();

public:
    virtual CLinkUser* CreateUser(int nOrigin);

public:
    virtual void OnTimeOut(time_t tNow);
    
public:
    int OnCreateRoom(int64_t sesID, int& nRoomID);

    int JoinRoom(int64_t sesID, int& nRoomID, ClientUser* pUser);

    int OnSendRoomMsg(int64_t sesID, int nRoomID, std::string& msg);

    int OnClientBreak(int64_t sesID);

private:
    RoomMgr m_roomMgr;
};

extern ChatService* g_pService;

服务继承于基类NetService,并重写了两个基类函数CreateUser(int nOrigine)和OnTimeOut(time_t tNow)。

CreateUser函数根据数据来源,确认连接者身份,并生成对应的连接对象,在这里是ClientUser代表客户端连接对象。

CLinkUser* ChatService::CreateUser(int nOrigin)
{
    switch(nOrigin)
    {
        case ORIGINE_CLIENT:
        return new ClientUser();
    }
    return nullptr;
}

在程序开发中,尽量使用命名常量替代具体的数字,这有两个好处:1是代码容易阅读理解,2是多处使用的时候,如果需要修改,只需修改定义赋值的地方。此处标识客户端来源定义的变量是ORIGINE_CLIENT,其定义放在了ChatProtocol.h中

#pragma once
#include "Protocol.h"

const int ORIGINE_CLIENT = 1;

const int ORIGINE_CHATSVR = 2001;

当客户端发送消息到服务端时,服务端先根据客户端Header中的Origine属性,调用服务重写的CreateUser函数,得到对应的User对象。基类实现的具体流程参见 《第二章第二节 增加监听端口》一节的内容。

OnTimeOut函数提供了一个30秒的定时轮询,每隔30秒触发一次函数调用,用于服务常规的定时检测,ChatService中的实现为

void ChatService::OnTimeOut(time_t tNow)
{
   m_roomMgr.Check();
}

另外,服务的构造函数中给一些变量进行赋值。首先给全局变量g_pService赋值,便于服务其他地方调用服务函数。m_nPort是继承自NetService的成员变量,赋值后服务将监听这个端口。

SetLogName函数设置了服务输出日志的文件名,如果不设置,默认输出到ServiceBase.log文件中。

#include "ChatService.h"
#include "ClientUser.h"
#include "Protocol.h"
#include <iostream>
#include "HYLog.h"
#include "HYFunc.h"


ChatService* g_pService = nullptr;

ChatService::ChatService()
{
    g_pService = this;
    m_nPort = 21100;
    SetLogName("./ChatService.log");
}

以上便基于服务框架创建了一个新的服务,可以监听服务自定义的端口,输出日志到指定文件,每隔30秒定期执行一次函数回调。

下一节,我们介绍ClientUser的实现。

Previous2 概要设计Next4 ClientUser实现

Last updated 2 years ago