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. 四、一个聊天服务

7 RoomIDMgr实现

房间的ID是六位数,取值范围是100000-999999,房间ID不能重复,因为字段有限,需要重复利用,所以有必要使用一个专门的类用来分配管理ID的使用。

当然实现起来也很简单

#pragma once
#include <queue>
#include <mutex>

typedef std::mutex Mutex;
typedef std::lock_guard<Mutex> AutoLock;

class RoomIDMgr
{
public:
    RoomIDMgr();

    int GetID();

    void Recycle(int ID);

public:
    std::queue<int> m_queueIDs;
    Mutex m_lock;
};
#include "RoomIDMgr.h"

const int MIN_ROOMID = 100000;
const int MAX_ROOMID = 999999;

 RoomIDMgr::RoomIDMgr()
 {
    for(int i = MIN_ROOMID; i <= MAX_ROOMID; ++i)
    {
        m_queueIDs.push(i);
    }
 }

int RoomIDMgr::GetID()
{
    AutoLock lock(m_lock);
    int id = m_queueIDs.front();
    m_queueIDs.pop();
    return id;
}

void RoomIDMgr::Recycle(int ID)
{
    AutoLock lock(m_lock);
    m_queueIDs.push(ID);
}

这里使用了一个队列,初始化的时候,将所有的可用ID按顺序填充到队列中,取ID时从队头弹出一个,回收时将其放入队尾。

取用和回收操作,都使用了锁进行线程保护。

这个类本身没什么好说的。一个简单的区间数据分配功能,即使不单独写类,在RoomMgr中增加一个成员变量也能简单的实现。

这里之所以单独提出一个单独的类,主要基于两点考虑:

1、RoomMgr类职责尽量单一;

2、IDMgr后期可能存在需求变动,单独提出便于维护。

需求变动举几个例子:现在取值范围是一个连续的区间,后期可能需要改为几个区间[100000,500000)(800000,999999],预留一部分[500000,800000]专用;或者其中一部分靓号666666,888888需要预留出来,不能系统直接分配;聊天室承载数量有出现瓶颈,需要分布式部署,多个聊天室服务在不同的机器上,但房间ID要统一管理,不能重复。

所以,如果ID分配写到RoomMgr类里,虽然前期省事,后面需求变动时,代码会越写越复杂,越维护越难看,最后重构又由于耦合太高,带来很高的风险。

因此,前期能够预见到的问题,需要在设计之初就将结构设计好,做好功能分离。而职责单一,是一种非常有用的设计原则。

Previous6 ChatRoom实现Next小结

Last updated 2 years ago