NGP处理包

NGP处理部分(主要就是这个RunOnce函数,客户单肯定是开个线程取调用这个RunOnce的)
void NGP::RunOnce()
{
    m_spTimerFac->driveTimer();//客户端心跳包驱动

    //先检查一下其他命令
    if(m_queFunctions.size())
    {
        for (;;)
        {
            std::function<void()> fun;
            {
                std::lock_guard<std::mutex> lock(m_PktMutex);
                fun = m_queFunctions.front();
            }
            fun();
            {
                std::lock_guard<std::mutex> lock(m_PktMutex);
                m_queFunctions.pop();
            }
            if(0 == m_queFunctions.size())
                break;
        }
    }
    //检查数据包,一次最少处理10个命令
    for (int i = 0; i < 20; i++)
    {
        if (m_quePktQueue.size() == 0)
            break;

        date_pkt pkt;
        {
            std::lock_guard<std::mutex> lock(m_PktMutex);
            pkt = m_quePktQueue.front();
            m_quePktQueue.pop();
        }
        ProcessDate(pkt.date, pkt.len);
        delete[] pkt.date;
    }
    //_TcpLink->run_one();
}

连接事件就这几个
OnConnectFailed--->直接连接失败了,在bufferevent_socket_connect,这个就相当于socket里面的connect
OnConnected--->连接成功了
OnDisconnected--->这个是服务端突然蹦了,这样客户端也能收到通知

这些事件相应的绑定函数放到m_queFunctions队列中,runonce可以直接调用传递进来的绑定函数
bool NGP::OnRec(void* pBuffer, int nSize)
{
    date_pkt pkt;
    pkt.len = nSize;
    pkt.date = new char[nSize];//注意在runonce中释放内存
    memcpy(pkt.date, pBuffer, nSize);
    {
        std::lock_guard<std::mutex> lock(m_PktMutex);
        m_quePktQueue.push(pkt);
    }
    return true;
}
对于接收的包放到m_quePktQueue,在初始化的时候会创建一个map,key是协议,value是绑定好的函数对象,在runonce中
使用protocol来解析发送过来的包,这个包是符合协议的,那么第一个字节就是协议,后面是长度和内容,然后根据协议查找map,调用绑定好的函数。
根据协议类型调用绑定函数这种方法在服务器很多。
对于协议解析和中间的线程加锁理解不是太好
原文地址:https://www.cnblogs.com/zzyoucan/p/4088592.html