【TARS】TARS-CPP服务器端数据结构总结

1. 基础数据结构

1.0 记录文件

tarsImportantClass.cpp

1.1 TC_ThreadRecMutex

 

1.2 TC_HandleBase

1.3 BaseNotify

1.4 NotifyObserver

1.5 Application

  

1.6 TC_Config

1.7 Communicator

1.8 TC_EpollServer

TC_EpollServer内部嵌套的类:

class SendContext;
class RecvContext;
class Handle;
class BindAdapter;
class Connection;
class ConnectionList;
class NetThread;

1.9 TC_EpollServer::NotifyInfo

  class NotifyInfo
    {
	public:
        NotifyInfo();
		~NotifyInfo();
        void init(TC_Epoller *ep); // 初始化
		void add(uint64_t data);   // 添加关联数据
        void notify();             // 通知notify醒过来
        void release();            // 释放掉
		int notifyFd();            // 获取通知fd
	protected:
        TC_Socket _notify;  // 通知fd
		TC_Epoller *_ep;    // 
		uint64_t _data;		//关联到通知句柄的事件

    };

1.10 TC_Epoller

 

1.11 NetThread(TC_EpollServer的内嵌类)

搜索关键字 “class NetThread”,构造函数搜索“TC_EpollServer::NetThread::NetThread”

 class NetThread : public TC_Thread, public TC_HandleBase
    {
    public:
    public:
        NetThread(TC_EpollServer *epollServer, int index); // 构造函数
        virtual ~NetThread(); // 析构函数
		int getIndex() const { return _threadIndex; } // 获取网络线程的index
        virtual void run();// 网络线程执行函数
        void terminate(); // 停止网络线程
        void createEpoll(uint32_t maxAllConn); // 生成epoll
        void initUdp(const unordered_map<int, BindAdapterPtr> &listeners); // 初始化udp监听
        bool isTerminate() const    { return _bTerminate; } // 是否服务结束了
        TC_Epoller* getEpoller()    { return &_epoller; }// 获取Epoller对象
		void notify(); // 唤醒网络线程
		void close(const shared_ptr<RecvContext> &data); // 关闭连接
		void send(const shared_ptr<SendContext> &data); // 发送数据
		vector<TC_EpollServer::ConnStatus> getConnStatus(int lfd); // 获取某一监听端口的连接数
        size_t getConnectionCount(){ return _list.size(); } // 获取连接数
        void debug(const string &s) const; // 记录日志
        void info(const string &s) const; // INFO日志
	    void tars(const string &s) const; // TARS日志
        void error(const string &s) const;// 记录错误日志
        void enAntiEmptyConnAttack(bool bEnable); // 是否启用防止空链接攻击的机制
        void setEmptyConnTimeout(int timeout);// 设置空连接超时时间
        void setUdpRecvBufferSize(size_t nSize=DEFAULT_RECV_BUFFERSIZE);// 设置udp的接收缓存区大小,单位是B,最小值为8192,最大值为DEFAULT_RECV_BUFFERSIZE
    protected:
        Connection *getConnectionPtr(uint32_t uid){ return _list.get(uid); } // 获取连接
        void addTcpConnection(Connection *cPtr);// 添加tcp链接
        void addUdpConnection(Connection *cPtr);// 添加udp连接
        void delConnection(Connection *cPtr, bool bEraseList = true, EM_CLOSE_T closeType=EM_CLIENT_CLOSE);// 删除链接
        void processPipe(); // 处理管道消息
        void processNet(const epoll_event &ev); // 处理网络请求
        int getEmptyConnTimeout() const;  // 空连接超时时间
        bool isEmptyConnCheck() const;    // 是否空连接检测
        friend class BindAdapter;
        friend class ConnectionList;
        friend class TC_EpollServer;
    private:
        TC_EpollServer              *_epollServer; // 服务
		std::thread::id             _threadId;// net线程的id
		int                         _threadIndex; // 线程索引
        TC_Epoller                  _epoller; // epoll
        bool                        _bTerminate; // 停止标志
		TC_Epoller::NotifyInfo 		_notify; // 通知epoll
        ConnectionList              _list;   // 管理的连接链表
        send_queue                  _sbuffer;// 发送队列
        bool                        _bEmptyConnAttackCheck;
        int                         _iEmptyCheckTimeout; // 空连接超时时间,单位是毫秒,默认值2s,该时间必须小于等于adapter自身的超时时间
        size_t                      _nUdpRecvBufferSize;// udp连接时接收包缓存大小,针对所有udp接收缓存有效
		bool                        _notifySignal = false; //通知信号
    };

 

1.12 BindAdapter(TC_EpollServer的内部类及友元类)

 

 

1.13 TC_Endpoint

 

1.14 ServantHelperManager

1.15 NotifyObserver

 

1.16 PropertyReport

1.17 DataQueue

struct DataQueue
{
			recv_queue      _rbuffer;//接收的数据队列
			TC_ThreadLock   _monitor;//锁
};

typedef TC_ThreadQueue<shared_ptr<RecvContext>> recv_queue;

接受队列 BindAdapter中有接受队列的集合_threadDataQueue,搜索 TARS基金会CPP服务器文章链接的关键词“接收队列”

1.18 TC_ThreadQueue【线程安全队列】

template<typename T, typename D = deque<T> >
class TC_ThreadQueue
{
public:
    TC_ThreadQueue():_size(0){};
public:

    typedef D queue_type;
	T front();//从头部获取数据, 没有数据抛异常 
    bool pop_front(T& t, size_t millsecond = 0, bool wait = true);// 从头部获取数据, 没有数据则等待.
	bool pop_front();// 从头部获取数据.
    void notifyT();// 通知等待在队列上面的线程都醒过来
    void push_back(const T& t, bool notify = true);// 放数据到队列后端. 
    void push_back(const queue_type &qt, bool notify = true); // 放数据到队列后端. 
    void push_front(const T& t, bool notify = true);// 放数据到队列前端. 
    void push_front(const queue_type &qt, bool notify = true);// 放数据到队列前端. 
    bool swap(queue_type &q, size_t millsecond = 0, bool wait = true);// 交换数据
    size_t size() const;// 队列大小.
    void clear();// 清空队列
    bool empty() const;// 是否数据为空.

protected:
	TC_ThreadQueue(const TC_ThreadQueue&) = delete;
	TC_ThreadQueue(TC_ThreadQueue&&) = delete;
	TC_ThreadQueue& operator=(const TC_ThreadQueue&) = delete;
	TC_ThreadQueue& operator=(TC_ThreadQueue&&) = delete;

protected:
    queue_type              _queue; // 队列
    size_t                  _size;  // 队列长度
	std::condition_variable _cond;  //条件变量
    mutable std::mutex      _mutex; //锁
};

1.19 RecvContext【接收包的上下文】

class RecvContext : public std::enable_shared_from_this<RecvContext> // 接收包的上下文
{
	public:
		RecvContext(uint32_t uid, const string &ip, int64_t port, int fd, const BindAdapterPtr &adapter, bool isClosed = false, int closeType = EM_CLIENT_CLOSE)
			: _uid(uid), _ip(ip), _port(port), _fd(fd), _adapter(adapter), _isClosed(isClosed), _closeType(closeType), _recvTimeStamp(TNOWMS)
		{
		}
		uint32_t uid()       const       { return _uid; }
		const string &ip()   const       { return _ip; }
		uint16_t port()      const       { return _port; }
		vector<char> &buffer()           { return _rbuffer; }
		const vector<char> &buffer()  const { return _rbuffer; }
		int64_t recvTimeStamp() const    { return _recvTimeStamp; }
		bool isOverload()       const    { return _isOverload; }
		void setOverload()               { _isOverload = true; }
		bool isClosed()         const    { return _isClosed; }
		int fd()             const       { return _fd; }
		BindAdapterPtr &adapter()    { return _adapter; }
		int closeType()      const       { return _closeType; }
		void setCloseType(int closeType) { _closeType = closeType;}
		shared_ptr<SendContext> createSendContext()  { return std::make_shared<SendContext>(shared_from_this(), 's'); }
		shared_ptr<SendContext> createCloseContext() { return std::make_shared<SendContext>(shared_from_this(), 'c'); }

	protected:
		uint32_t        _uid;               /**连接标示*/
        string          _ip;                /**远程连接的ip*/
        uint16_t        _port;              /**远程连接的端口*/
        int				_fd;				/*保存产生该消息的fd,用于回包时选择网络线程*/
        BindAdapterPtr  _adapter;           /**标识哪一个adapter的消息*/
        vector<char>    _rbuffer;                /**接收的内容*/
        bool            _isOverload = false;     /**是否已过载 */
        bool            _isClosed   = false;       /**是否已关闭*/
        int             _closeType;     /*如果是关闭消息包,则标识关闭类型,0:表示客户端主动关闭;1:服务端主动关闭;2:连接超时服务端主动关闭*/
        int64_t         _recvTimeStamp;  /**接收到数据的时间*/
};

1.20 SendContext【发送包的上下文,由RecvContext创建出来】

class SendContext // 发送包的上下文,由RecvContext创建出来
{
	public:
		SendContext(const shared_ptr<RecvContext> &context, char cmd) : _context(context), _cmd(cmd)
		{
			_sbuffer = std::make_shared<TC_NetWorkBuffer::Buffer>();
		}
		const shared_ptr<RecvContext> &getRecvContext() { return _context; }
		const shared_ptr<TC_NetWorkBuffer::Buffer> & buffer()       { return _sbuffer; }
		char cmd() const        { return _cmd; }
		uint32_t uid() const    { return _context->uid(); }
		int fd() const          { return _context->fd(); }
		const string &ip() const { return _context->ip(); }
		uint16_t port() const   { return _context->port(); }
		friend class RecvContext;
	protected:
		shared_ptr<RecvContext>     _context;
		char                        _cmd;                     /**send包才有效, 命令:'c',关闭fd; 's',有数据需要发送*/
		shared_ptr<TC_NetWorkBuffer::Buffer> _sbuffer;        /**发送的内容*/
};

1.21 send_queue

typedef TC_ThreadQueue<shared_ptr<SendContext>> send_queue; // 发送队列

发送队列,send_queue _sbuffer;--发送队列,在D:\005-02-代码\016-TARS\TARS\TarsFramework\tarscpp\util\include\util\tc_epoll_server.h文件中的NetThread类中

NetThread类中有发送队列,搜索 TARS基金会CPP服务器文章链接的关键词“发送队列”

1.22  recv_queue

 typedef TC_ThreadQueue<shared_ptr<RecvContext>> recv_queue; // 接受队列

// 数据队列
struct DataQueue
{
			recv_queue      _rbuffer;// 接收的数据队列
			TC_ThreadLock   _monitor;// 锁
};

/**
* 每个线程都有自己的队列
* 0: 给共享队列模式时使用
* 1~handle个数: 队列模式时使用
* Every thread has its own queue.
* 0: Use when sharing queue mode
* 1~handle count: Use when queue mode
*/

class BindAdapter : public TC_HandleBase{
...
vector<shared_ptr<DataQueue>> _threadDataQueue;
...
}

1.23 ServantHandle

class ServantHandle : public TC_EpollServer::Handle
{
public:
    enum{ HEART_BEAT_INTERVAL = 10, /**定义常量,心跳间隔时间**/};
    ServantHandle(Application *application);// 构造
    ~ServantHandle();// 析构
	virtual void run();// 线程处理方法
    CoroutineScheduler* getCoroSched() { return _coroSched; }// 获取协程调度器
	Application *getApplication() { return _application; }   // get Application

protected:
    virtual void handleRequest();// 处理接收请求的协程函数
    virtual void handleRecvData(const shared_ptr<TC_EpollServer::RecvContext> &data);// 处理请求的协程函数

protected:
    void initialize();// 线程初始化
    virtual void handle(const shared_ptr<TC_EpollServer::RecvContext> &data);// 逻辑处理
    virtual void handleTimeout(const shared_ptr<TC_EpollServer::RecvContext> &data);// 超时处理
    virtual void handleOverload(const shared_ptr<TC_EpollServer::RecvContext> &data);// 处理
    virtual void handleClose(const shared_ptr<TC_EpollServer::RecvContext> &data);// 事件处理
	virtual void handleAsyncResponse();// handleFilter拆分的第一部分,处理异步调用队列
    virtual void handleCustomMessage(bool bExpectIdle = false);// handleFilter拆分的第二部分,处理用户自有数据,非游戏逻辑可忽略bExpectIdle参数
    virtual void heartbeat();// 心跳
    virtual bool allFilterIsEmpty();// 检查servant有没有resp消息待处理
	CurrentPtr createCurrent(const shared_ptr<TC_EpollServer::RecvContext> &data);// 创建上下文
    CurrentPtr createCloseCurrent(const shared_ptr<TC_EpollServer::RecvContext> &data);// 创建闭连接时的关上下文
    void handleTarsProtocol(const TarsCurrentPtr &current);// 处理Tars协议
    void handleNoTarsProtocol(const TarsCurrentPtr &current);// 处理非Tars协议

#ifdef TARS_OPENTRACKING
    void processTracking(const TarsCurrentPtr &current);//处理TARS下的调用链逻辑
    void finishTracking(int ret, const TarsCurrentPtr &current);
#endif
    bool processDye(const CurrentPtr &current, string& dyeingKey);// 处理TARS下的染色逻辑
    bool processCookie(const CurrentPtr &current, map<string, string> &cookie);// 处理cookie
	bool checkValidSetInvoke(const CurrentPtr &current);// 检查set调用合法性
protected:
	Application *_application = NULL;// application
    unordered_map<string, ServantPtr> _servants;// 处理对象
    CoroutineScheduler     *_coroSched;// 协程调度器

#ifdef TARS_OPENTRACKING
    map<int,std::unique_ptr<opentracing::Span>> _spanMap;
#endif
};

1.24 Handle(TC_EpollServer的嵌套类)

/**
* 服务的逻辑处理代码
* Logical Processing Code for Services
*/
class Handle : public TC_Thread, public TC_HandleBase
{
    public:
        Handle();//构造, 默认没有请求, 等待10s
        virtual ~Handle();// 析构函数
		TC_EpollServer* getEpollServer() const { return _pEpollServer; };// 获取服务
		BindAdapter *getBindAdapter() const { return _bindAdapter; }     // 获取adapter
		uint32_t getHandleIndex() const { return _handleIndex; }        // 获取Handle的索引(0~handle个数-1)
		void setNetThread(NetThread *netThread);// 设置网络线程
		NetThread *getNetThread() { return _netThread; } // 获取网络线程
		void process(shared_ptr<RecvContext> data); // 处理
        virtual void run(); // 线程处理方法
    public:
		void sendResponse(const shared_ptr<SendContext> &data); // 发送数据
        void close(const shared_ptr<RecvContext> &data); // 关闭链接
        void setWaitTime(uint32_t iWaitTime); // 设置等待时间
        virtual void initialize() {}; // 对象初始化
        virtual void notifyFilter(); // 唤醒handle对应的处理线程
        virtual void heartbeat() {}  // 心跳(每处理完一个请求或者等待请求超时都会调用一次)
    protected:
        virtual void handleImp(); // 具体的处理逻辑
		virtual void handle(const shared_ptr<RecvContext> &data) = 0; // 处理函数
		virtual void handleTimeout(const shared_ptr<TC_EpollServer::RecvContext> &data); // 处理超时数据, 即数据在队列中的时间已经超过
		virtual void handleClose(const shared_ptr<TC_EpollServer::RecvContext> &data);// 处理连接关闭通知(具体看源码)
		virtual void handleOverload(const shared_ptr<TC_EpollServer::RecvContext> &data);// 处理overload数据 即数据队列中长度已经超过允许值
        virtual void handleAsyncResponse() {} // 处理异步回调队列
        virtual void handleCustomMessage(bool bExpectIdle = false) {} // handleFilter拆分的第二部分,处理用户自有数据
        virtual void startHandle() {} // 线程已经启动, 进入具体处理前调用
        virtual void stopHandle() {} // 线程马上要退出时调用
        virtual bool allAdapterIsEmpty(); // 是否所有的Adpater队列都为空
		virtual bool allFilterIsEmpty(); // 是否所有的servant都没有resp消息待处理
		void setEpollServer(TC_EpollServer *pEpollServer); // 设置服务
		void setBindAdapter(BindAdapter*  bindAdapter); // 设置Adapter
		void setHandleIndex(uint32_t index); // 设置index
		void wait();// 等待在队列上
		bool popRecvQueue(shared_ptr<RecvContext> &recv);// 从队列中获取数据
        friend class BindAdapter;// 友元类
    protected:
        TC_EpollServer  *_pEpollServer;// 服务
		NetThread       *_netThread = NULL;// handle对应的网路线程(网络线程和handle线程合并的情况下有效)
		BindAdapter*    _bindAdapter;// 所属handle组
		uint32_t        _iWaitTime;// 等待时间
		uint32_t        _handleIndex;// Handle的索引
};

1.25 Servant

class Servant : public BaseNotify
{
public:
    Servant(); // 构造函数
    ~Servant();// 析构函数
    void setName(const string &name);// 设置名称
    string getName() const;// 名称
    void setHandle(TC_EpollServer::Handle* handle);// 设置所属的Handle
    void setApplication(Application *application);// 设置全局的应用
    Application* getApplication() const;// 获取应用
    TC_EpollServer::Handle* getHandle();// 获取所属的Handle
    virtual void initialize() = 0;// 初始化
    virtual void destroy() = 0;// 退出

public:
    virtual int dispatch(CurrentPtr current, vector<char> &buffer);// 分发收到的请求
    virtual int onDispatch(CurrentPtr current, vector<char> &buffer) { return -1; }// 分发并处理请求

public:
    virtual int doRequest(CurrentPtr current, vector<char> &buffer) { return -1; }// 普通协议的请求,没有方法名,不需要Dispatch
    virtual int doResponse(ReqMessagePtr resp) { return -1; }// 作为客户端访问其他server时,成功返回的响应接口
    virtual int doResponseException(ReqMessagePtr resp) { return -1; }// 作为客户端访问其他server时,返回其他异常的响应接口
    virtual int doResponseNoRequest(ReqMessagePtr resp) { return -1; }// 作为客户端访问其他server时,如果resp没有找到request,则响应该接口
    virtual int doCustomMessage(bool bExpectIdle) { return -1; }// 处理消息
    virtual int doCustomMessage() { return -1; }// doCustomMessage() 不带参数的是为了兼容老版本。尽量用带参数的函数
	virtual int doClose(CurrentPtr current){ return -1; }// 客户端关闭连接时的处理
    TC_CasQueue<ReqMessagePtr>& getResponseQueue();// 获得响应的数据队列

protected:
    string _name;// 名字
    Application *_application;// 应用
    TC_EpollServer::Handle* _handle;// 所属的Handle
    TC_CasQueue<ReqMessagePtr> _asyncResponseQueue;// 异步响应队列(详情看源码)
};

1.25  Current

/**
 * 当前请求的上下文
 */
class Current : public TC_HandleBase
{
public:
    typedef std::map<string, string>    TARS_STATUS;
    typedef std::vector<char>           TARS_BUFFER; 
    Current(ServantHandle *pServantHandle);// 构造函数
    ~Current();// 析构
    const string &getIp() const;// 获取IP
	const string &getHostName() const;//  get host name
    int getPort() const;// 获取端口
	uint32_t getUId() const;// 获取uid
	int getFd() const { return _data->fd(); }// 获取fd
    bool isResponse() const;// 是否函数返回时发送响应包给客户端
    void setCloseType(int type);// 设置连接的关闭类型,详情参看TC_EpollServer::EM_CLOSE_T
    int getCloseType() const;// 获取连接关闭类型,详情请参考TC_EpollServer::EM_CLOSE_T类型
    void setResponse(bool value) { _response = value; }// 设置是否自动回响应包
    void setResponseContext(const map<std::string, std::string> & context){_responseContext = context;}// 设置返回的context(仅TARS协议有效)
    const map<std::string, std::string> & getResponseContext() const {return _responseContext;}//获取返回的context(仅TARS协议有效)
    void close();// 关闭当前连接
    ServantHandle* getServantHandle();// 获取所属的ServantHandle
    TC_EpollServer::BindAdapter* getBindAdapter();// 获取来源的Adapter
    const vector<char> &getRequestBuffer() const; // 获取请求buffer
    string getServantName() const;// 获取服务Servant名称
    short getRequestVersion() const;// 请求的协议的版本号(仅TARS协议有效)
    map<string, string>& getContext();// 扩展map(仅TARS协议有效)
    const map<string, string>& getRequestStatus() const;// 获取保存状态信息,比如染色等(仅TARS协议有效)

    string getFuncName() const;// 获取函数名称(仅TARS协议有效)
    uint32_t getRequestId() const;// 请求ID(仅TARS协议有效)
    char getPacketType() const;// 获取包类型(仅TARS协议有效)
    Int32 getMessageType() const;// 获取消息类型(仅TARS协议有效)
	struct timeval getRecvTime() const; // 获取接收到请求的时间
	void setReportStat(bool bReport);// 设置是否上报状态报告
    void sendResponse(int iRet);// taf协议的发送响应数据(仅TAF协议有效)
	void sendResponse(int iRet, tars::TarsOutputStream<tars::BufferWriterVector>& os);// taf协议的发送响应数据(仅TAF协议有效), 直接swapbuffer , 这样可以不用copy 数据
	void sendResponse(int iRet, tup::UniAttribute<tars::BufferWriterVector, tars::BufferReader>& attr);// taf协议的发送响应数据(仅TAF协议有效), 直接swapbuffer , 这样可以不用copy数据
	void sendResponse(int iRet, const vector<char> &buff); // taf协议的发送响应数据(仅TAF协议有效)
    void sendResponse(const char* buff, uint32_t len);// 普通协议的发送响应数据(非TAF协议有效)
	void sendResponse(int iRet, ResponsePacket &response, const map<string, string>& status, const string& sResultDesc);// 发送响应数据
protected:
    friend class ServantHandle;
    friend class Application;
    void initialize(const shared_ptr<TC_EpollServer::RecvContext> &data); // 初始化
    void initializeClose(const shared_ptr<TC_EpollServer::RecvContext> &data);// 初始化
    void initialize(const vector<char> &sRecvBuffer);  // 初始化
    void reportToStat(const string & sObj);            // 服务端上报状态,针对单向调用及WUP调用(仅对TAF协议有效)
    void setCookie(const map<string, string> &cookie); // 设置cookie
    map<string, string> & getCookie();                 // 获取cookie
protected:
    ServantHandle*            _servantHandle;       // 操作类指针
	shared_ptr<TC_EpollServer::RecvContext> _data; // 接收到的数据
    RequestPacket            _request;             // 客户端请求包
    bool                    _response;             // 响应
    int                     _ret;                  // 接口处理的返回值
    bool                    _reportStat;           // 是否上报stat
    map<std::string, std::string> _responseContext;// 设置额外返回的内容
    map<string, string>             _cookie;       // cookie
};

 

2. 类间关系

2.1 网络模块

 

图(2-16)服务端接受一个客户端连接

 

图(2-15)网络模块类图

图中的BindAdapter中的_rBufQueue在我的2.4.14版本中已经变成了vector<shared_ptr<DataQueue>> _threadDataQueue;

 

2.2 业务模块

图(2-10)再看业务模块相关类图

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值