mprpc框架的配置文件加载

发布于:2024-06-25 ⋅ 阅读:(153) ⋅ 点赞:(0)

目录

1.回顾测试

2.mprpc框架的配置文件加载

2.1 mprpcconfig.h

2.2 完善mprpcapplication.h

 2.3 完善mprpcapplication.cc

2.4 mprpcconfig.cc 

2.5 test.conf

2.6 测试运行

​3.扩展问题


1.回顾测试

我们先把之前的项目代码工程编译好,然后进入bin里面,执行
./provider

显示我们之前编的代码正确了!
接下来,我们开始编写配置文件

2.mprpc框架的配置文件加载

一开始编写的代码,读取配置文件信息时没有处理好,导致打印结果有多余的空行。

调试信息如下:

 

 

由上图可见是多读了一个\n导致的,更改后如下: 

2.1 mprpcconfig.h

在src的include中创建头文件:mprpcconfig.h

#pragma once

#include <unordered_map>
#include <string>

//rpcserverip  rpcserverport  zookeeperip   zookeeperport
//框架读取配置文件类
class MprpcConfig
{
public:
    //负责解析加载配置文件
    void LoadConfigFile(const char* config_file);
    //查询配置项信息
    std::string Load(const std::string& key);//返回key所对应的值-字符串 
private:
    std::unordered_map<std::string,std::string> m_configMap;
    //去掉字符串前后的空格
    void Trim(std::string& src_buf);
};

2.2 完善mprpcapplication.h

#pragma once
#include "mprpcconfig.h"

//mprpc框架的基础类,负责框架的一些初始化操作
class MprpcApplication
{
public:
    static void Init(int argc,char** argv);//初始化
    //单例模式
    static MprpcApplication& GetInstance();//定义获取唯一实例的方法

private:
    static MprpcConfig m_config;
    MprpcApplication(){}//构造函数
    MprpcApplication(const MprpcApplication&)=delete;//将与拷贝构造有关的函数delete
    MprpcApplication(MprpcApplication&&) = delete;
};

 2.3 完善mprpcapplication.cc

#include "mprpcapplication.h"
#include <iostream>
#include <unistd.h>

MprpcConfig MprpcApplication::m_config;

void ShowArgsHelp()
{
    std::cout<<"format: command -i <configfile>"<<std::endl;
}

void MprpcApplication::Init(int argc, char **argv) // 初始化
{
    if(argc<2)
    {
        ShowArgsHelp();
        exit(EXIT_FAILURE);
    }

    int c=0;
    std::string config_file;
    while((c=getopt(argc,argv,"i:"))!=-1)
    {
        switch(c)
        {
        case 'i':
            config_file=optarg;
            break;
        case '?':
            //std::cout<<"invalid args!"<<std::endl;
            ShowArgsHelp();
            exit(EXIT_FAILURE);
        case ':':
            //std::cout<<"need <configfile>"<<std::endl;
            ShowArgsHelp();
            exit(EXIT_FAILURE);
        default:
            break;
        }
    }

    //开始加载配置文件了 rpcserver_ip=  rpcserver_port   zookeeper_ip=  zookeeper_port=
    m_config.LoadConfigFile(config_file.c_str());

    // std::cout<<"rpcserverip:"<<m_config.Load("rpcserverip")<<std::endl;
    // std::cout<<"rpcserverport:"<<m_config.Load("rpcserverport")<<std::endl;
    // std::cout<<"zookeeperip:"<<m_config.Load("zookeeperip")<<std::endl;
    // std::cout<<"zookeeperport:"<<m_config.Load("zookeeperport")<<std::endl;
}
// 单例模式
MprpcApplication &MprpcApplication::GetInstance() // 定义获取唯一实例的方法
{
    static MprpcApplication app;
    return app;
}

2.4 mprpcconfig.cc 

在src下创建文件mprpcconfig.cc 

#include "mprpcconfig.h"

#include <iostream>

//负责解析加载配置文件
void MprpcConfig::LoadConfigFile(const char* config_file)
{
    FILE* pf=fopen(config_file,"r");
    if(nullptr==pf)
    {
        std::cout<<config_file<<" is note exist!"<<std::endl;
        exit(EXIT_FAILURE);
    }

    //1.注释  2.正确的配置项 =   3.去掉开头的多余空格
    while(!feof(pf))
    {
        char buf[512]={0};
        fgets(buf,512,pf);

        //去掉字符串前面多余的空格
        std::string read_buf(buf);
        Trim(read_buf);
        

        //判断#的注释
        if(read_buf[0]=='#'||read_buf.empty())
        {
            continue;
        }

        //解析配置项
        int idx=read_buf.find('=');
        if(idx==-1)
        {
            //配置项不合法
            continue;
        }

        std::string key;
        std::string value;
        key=read_buf.substr(0,idx);
        Trim(key);
        //rpcserverip=127.0.0.1\n   
        int endidx=read_buf.find('\n',idx);//从等号之后开始寻找\n
        value=read_buf.substr(idx+1,endidx-idx-1);
        Trim(value);
        m_configMap.insert({key,value});
    }
}

// 查询配置项信息
std::string MprpcConfig::Load(const std::string &key)
{
    //return m_configMap[key];//不要使用[],会产生副作用,正常情况key如果不存在,会返回空,可是用[]的话,会在map表中增加一对值
    auto it=m_configMap.find(key);
    if(it==m_configMap.end())
    {
        return "";
    }
    return it->second;
}

void MprpcConfig::Trim(std::string &src_buf)
{
    int idx = src_buf.find_first_not_of(' ');
    if (idx != -1)
    {
        // 说明字符串前面有空格
        src_buf = src_buf.substr(idx, src_buf.size() - idx); // 第一个参数是下标,第二个是长度
    }

    // 去掉字符串后面多余的空格
    idx = src_buf.find_last_not_of(' ');
    if (idx != -1)
    {
        // 说明字符串后面有空格
        src_buf = src_buf.substr(0, idx + 1);
    }
}

2.5 test.conf

在bin下创建一个配置文件:test.conf

#rpc节点的ip地址
rpcserverip=127.0.0.1
#rpc节点的port端口号
rpcserverport=8000
#zk的ip地址
zookeeperip=127.0.0.1
#zk的port端口号
zookeeperport=5000

2.6 测试运行

 编译:

测试结果:

 3.扩展问题

C++中的容器都不是线程安全的,需要解决这个问题吗? 

不需要考虑线程安全,因为整个提供rpc服务的站点启动以后,框架只需要init一次,不需要多线程。为了防止框架被多次初始化,可以在mprpcapplication.h文件中添加一个静态变量,来记录框架是否被初始化。


网站公告

今日签到

点亮在社区的每一天
去签到