å¾®æå¡å¼æºæ¡æ¶TARS ä¹ åºç¡ç»ä»¶
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIwIjNx8CX39CXy8CXycXZpZVZnFWbp9zZlBnauITbmhzcxYHb3h3LcFjM3ADM1czLcVmdhNXLwRHdo9CXt92YucWbpRWdvx2Yx5yazF2Lc9CX6MHc0RHaiojIsJye.jpeg)
ä½è herman
导è¯
æ¬ææºèªhermançç³»åæç« ä¹ä¸ãé¹ åå¼æºæ¡æ¶TARSä¹åºç¡ç»ä»¶ããç¸å ³ä»£ç å·²æTARSå¼æºç¤¾åºææ°çæ¬æ´æ°ã
TARSå¼æºæ¡æ¶åºéé¢ç¨C++å®ç°äºæ¯è¾å¤çå ¬ç¨ç»ä»¶ï¼è¿äºç»ä»¶ä¸è¬ç»ä¸æ¾å¨
util
æ件夹ï¼å¨åºç¨å±ä¹å¯ä»¥èªç±ä½¿ç¨ï¼å·¥æ¬²åå ¶äºå¿ å å©å ¶å¨ï¼æ以æå¿ è¦æè¿äºå·¥å ·ç»ä»¶åäºè§£ï¼æ´å¥½ç使ç¨ï¼æé«æçãæ¥ä¸æ¥ï¼æ¬æå°å¯¹å¦ä¸TarsCppç»ä»¶è¿è¡åæï¼
- 线ç¨æä½
- 线ç¨å®å ¨éå: TC_ThreadQueue
- æ®é线ç¨é: TC_ThreadLock
- 线ç¨åºç±»: TC_Thread
- æºè½æé
- æºè½æéç±»: TC_AutoPtr
- DBæä½
- MySQLæä½ç±»: TC_Mysql
- ç½ç»æä½
- ç½ç»ç»ä»¶
- æå¡é
ç½®
- å½ä»¤è§£æç±»: TC_Option
- é ç½®æ件类: TC_Config
- 仿å½æ°
- éç¨ä»¿å½æ°ç±»: TC_Functor
- Hash
- hashç®æ³
- å¼å¸¸å¤ç
- å¼å¸¸ç±»: TC_Exception
线ç¨å®å ¨éå: TC_ThreadQueue
å çä¸æ¡æ¶å¯¹
TC_ThreadQueue
ç±»ç使ç¨å¦ä¸ï¼
typedef TC_ThreadQueue<tagRecvData*, deque<tagRecvData*> > recv_queue; // æ¥æ¶éå
typedef TC_ThreadQueue<tagSendData*, deque<tagSendData*> > send_queue; // åééå
å¤å¶
TC_ThreadQueue
çå®ç°æ¯è¾ç®åï¼å¨TARSçç½ç»å±å®ç°ä¸å¯ä»¥åç°è¿ä¸ªç±»æ¯è¾éè¦ï¼å 为ä»æ¡æ¶ä¸æ¶å°çç½ç»å é½ä¼å å ¥å°è¿ä¸ªç¼åéåéé¢ï¼ç¶åå¤ä¸å¡çº¿ç¨
ServantHandle
ä¼è°ç¨
waitForRecvQueue
ä»è¯¥éåéé¢åç½ç»æ°æ®å ï¼ç¶åè°ç¨
dispatch
è°ç¨åè®®æ¶æ¯å¯¹åºçå¤çå½æ°ï¼å çä¸æ¡æ¶å¯¹
TC_ThreadQueue
çå®ç°ï¼
/**
* @brief 线ç¨å®å
¨éå
*/
template<typename T, typename D = deque<T> >
class TC_ThreadQueue
{
public:
TC_ThreadQueue():_size(0){};
public:
typedef D queue_type;
/**
* @brief ä»å¤´é¨è·åæ°æ®, 没ææ°æ®æå¼å¸¸
*
* @param t
* @return bool: true, è·åäºæ°æ®, false, æ æ°æ®
*/
T front();
/**
* @brief ä»å¤´é¨è·åæ°æ®, 没ææ°æ®åçå¾
.
*
* @param t
* @param millsecond(wait = trueæ¶æçæ) é»å¡çå¾
æ¶é´(ms)
* 0 表示ä¸é»å¡
* -1 æ°¸ä¹
çå¾
* @param wait, æ¯å¦wait
* @return bool: true, è·åäºæ°æ®, false, æ æ°æ®
*/
bool pop_front(T& t, size_t millsecond = 0, bool wait = true);
...
...
}
å¤å¶
TC_ThreadQueue
使ç¨äºC++11æ ååºä¸ç
<mutex>
å
<condition_variable>
ç¨äºå®ç°çº¿ç¨éå waitï¼å¦ä¸ï¼çä¸éåçæåå½æ°ï¼
push_front
å¨éååé¢å å ¥æ°æ®ï¼
template<typename T, typename D> void TC_ThreadQueue<T, D>::push_front(const T& t, bool notify)
{
if(notify) {
std::unique_lock<std::mutex> lock(_mutex);
_cond.notify_one();
_queue.push_front(t);
++_size;
}
else
{
std::lock_guard<std::mutex> lock (_mutex);
_queue.push_front(t);
++_size;
}
}
å¤å¶
å¦ä¸å¾è°ç¨
push_front
å½æ°çæ¶åè°ç¨
std::unique_lock<std::mutex> lock(_mutex)
å é ï¼é¿å ç½ç»å±æ¥æ¶æ°æ®åä¸å¡å±ååä¸éåçæ°æ®å²çªï¼
_cond.notify_one()
éç¥çå¾ å¨è¯¥éä¸æä¸ä¸ªçº¿ç¨éè¿æ¥ï¼è°ç¨è¯¥å½æ°ä¹åå¿ é¡»å éï¼å 为ææ°æ®è¿æ¥äºï¼ä¾å¦ç½ç»å±æ线ç¨éè¦åå 并è¿è¡ååå¤çã
åçä¸ä¸ªæåå½æ°
pop_front
ï¼ä»å¤´é¨è·åæ°æ®ï¼æ²¡ææ°æ®åçå¾ ã
millisecond
é»å¡çå¾ æ¶é´(ms)
- 表示ä¸é»å¡
-
æ°¸ä¹ çå¾-1
template<typename T, typename D> bool TC_ThreadQueue<T, D>::pop_front(T& t, size_t millsecond, bool wait)
{
if(wait) {
std::unique_lock<std::mutex> lock(_mutex);
if (_queue.empty()) {
if (millsecond == 0) {
return false;
}
if (millsecond == (size_t) -1) {
_cond.wait(lock);
}
else {
//è¶
æ¶äº
if (_cond.wait_for(lock, std::chrono::milliseconds(millsecond)) == std::cv_status::timeout) {
return false;
}
}
}
if (_queue.empty()) {
return false;
}
t = _queue.front();
_queue.pop_front();
assert(_size > 0);
--_size;
return true;
}
else
{
std::lock_guard<std::mutex> lock (_mutex);
if (_queue.empty())
{
return false;
}
t = _queue.front();
_queue.pop_front();
assert(_size > 0);
--_size;
return true;
}
}
å¤å¶
BindAdapter::waitForRecvQueue
çå½æ°å°±æ¯è°ç¨äº
pop_front
å½æ°ï¼ç¨äºçå¾ æ¥æ¶éåï¼å½æ°ååå¦ä¸ï¼
bool TC_EpollServer::BindAdapter::waitForRecvQueue(uint32_t handleIndex, shared_ptr<RecvContext> &data)
{
bool bRet = getRecvQueue(handleIndex).pop_front(data);
if (!bRet)
{
return bRet;
}
--_iRecvBufferSize;
return bRet;
}
å¤å¶
è¿é
BindAdapter::waitForRecvQueue
ç¨äºä¸å¡çº¿ç¨å¨çå¾ æå¡å¨çå¬çéé å¨æ¶å°ç½ç»å åè¿è¡ä¸å¡å çå¤çï¼è¿éä¼ å ¥ç
handleIndex
表示æ¥æ¶éåç´¢å¼ï¼è·å对åºç
_rbuffer
ã
æ®é线ç¨é: TC_ThreadLock
TC_ThreadLock
ç±»çå®ä¹å¦ä¸
typedef TC_Monitor<TC_ThreadMutex, TC_ThreadCond> TC_ThreadLock;
å¤å¶
TC_Monitor
线ç¨éçæ§æ¨¡æ¿ç±»ãé常线ç¨éï¼é½éè¿è¯¥ç±»æ¥ä½¿ç¨ï¼èä¸æ¯ç´æ¥ç¨
TC_ThreadMutex
ã
TC_ThreadRecMutex
ã
ç±»çå®ä¹
template <class T, class P> class TC_Monitor
éè¦ä¼ å ¥ä¸¤ä¸ªæ¨¡æ¿åæ°ï¼
TC_Monitor
å æ¬ä»¥ä¸æååéï¼
mutable int _nnotify; // ä¸éç次æ°
mutable P _cond; // æ¡ä»¶åé
T _mutex; // äºæ¥é
/**
* @brief å®ä¹éæ§å¶å¯¹è±¡
*/
typedef TC_LockT<TC_Monitor<T, P> > Lock;
typedef TC_TryLockT<TC_Monitor<T, P> > TryLock;
å¤å¶
第ä¸ä¸ªåæ°
TC_ThreadMutex
代表线ç¨éï¼åä¸ä¸ªçº¿ç¨ä¸å¯ä»¥éå¤å é ï¼å å«æååé
mutable std::mutex _mutex
å¤å¶
延伸é 读ï¼è¿éè¿å æ¬å¦å¤ä¸ä¸ªå¾ªç¯éç±»
tc_thread_mutex.h
ï¼å³ä¸ä¸ªçº¿ç¨å¯ä»¥å å¤æ¬¡éï¼å®ä¹å¦ä¸ï¼
TC_ThreadRecMutex
// å®ä¹äºtc_monitor.hä¸
typedef TC_Monitor<TC_ThreadRecMutex, TC_ThreadCond> TC_ThreadRecLock;
å¤å¶
第äºä¸ªåæ°
TC_ThreadCond
代表线ç¨ä¿¡å·æ¡ä»¶ç±»ï¼ææéå¯ä»¥å¨ä¸é¢çå¾ ä¿¡å·åçï¼å å«çº¿ç¨æ¡ä»¶æååéï¼
mutable std::condition_variable_any _cond
å¤å¶
ç»åå®é ç使ç¨åºæ¯ï¼
TC_Monitor::timedWait()
ä¼è°ç¨
TC_ThreadCond
对象ç
timedWait
å½æ°ï¼ä¸ä¸æ¥è°ç¨
chrono
åºç
milliseconds
ï¼
TC_ThreadCond::signal()
å®ç°åéä¿¡å·ï¼çå¾ å¨è¯¥æ¡ä»¶ä¸çä¸ä¸ªçº¿ç¨ä¼éã
TC_LockT
ç±»å®ä¹:
template <typename T> class TC_LockT
é模æ¿ç±»ï¼ä¸å ¶ä»å ·ä½éé å使ç¨ï¼æé æ¶åå éï¼æå¤çæ¶å解éã
TC_LockT
æé å½æ°ï¼ä¼ å ¥äºæ¥éåå§åæååé
_mutex
ï¼
TC_LockT
æé å½æ°å®ç°ï¼
TC_LockT(const T& mutex) : _mutex(mutex) {
_mutex.lock();
_acquired = true;
}
å¤å¶
å°è¿éå°±å¯ä»¥çåº
TC_Monitor
å®ä¹ç
typedef TC_LockT<TC_Monitor<T, P> > Lock
ï¼è¿é
Lock
ç±»åç模æ¿åæ°ç¨çæ¯
TC_Monitor
ç±»ã
å®é 使ç¨åºæ¯å¦ä¸ï¼
Lock lock(*this);
å¤å¶
TC_LockT
çæé å½æ°ï¼ä¼ å ¥åæ°
this
为
TC_Monitor
çå类对象ï¼
TC_LockT
çæé å½æ°è°ç¨
_mutex.lock()
ï¼å®é å°±æ¯è°ç¨äº
TC_Monitor
对象ç
lock
å½æ°ï¼
TC_Monitor
ç
lock
å½æ°å®ç°ï¼
void lock() const
{
_mutex.lock();
_nnotify = 0;
}
å¤å¶
è¿é
_mutex
为
TC_ThreadMutex
对象ï¼è¿ä¸æ¥è°ç¨äº
TC_ThreadRecMutex::lock()
æåå½æ°ï¼å®ç°å¦ä¸ï¼
void TC_ThreadMutex::lock() const
{
_mutex.lock();
}
å¤å¶
ç¶åä¸é¢å®ä¹çlockæ åééåºå½æ°çæ¶åè°ç¨
TC_LockT
çææå½æ°ï¼å®ç°å¦ä¸ï¼
virtual ~TC_LockT()
{
if (_acquired)
{
_mutex.unlock(); //è¿éä¼è°ç¨TC_Monitorçunlockå½æ°
}
}
å¤å¶
TC_Monitor
ç
unlock
å½æ°å®ç°ï¼
void unlock() const
{
notifyImpl(_nnotify);
_mutex.unlock(); //è¿éä¼è°ç¨C++æ ååº<mutex>ä¸çunlock
}
å¤å¶
è¿éè°ç¨
notifyImpl
å½æ°æ¯å 为
TC_Monitor
ç±»ä¸åªå¯ä»¥å®ç°ç®åçäºæ¥éåè½ï¼è¿å¯ä»¥å®ç°æ¡ä»¶åéConditionåè½ï¼å ¶ä¸
notifyImpl
çå®ç°ä¸º
void notifyImpl(int nnotify) const
{
if(nnotify != 0)
{
if(nnotify == -1)
{
_cond.broadcast();
return;
}
else
{
while(nnotify > 0)
{
_cond.signal();
--nnotify;
}
}
}
}
å¤å¶
线ç¨åºç±»: TC_Thread
è¿æ¯èæ ·åï¼å çä¸é¡¹ç®å®é 对线ç¨åºç±»ç使ç¨ãå®é 项ç®ä½¿ç¨ä¸ï¼æ们对
TC_Thread
åå°è£ äºä¸ä¸ï¼å®ç°äºä¸ä¸ª
BasicThread
ç±»ï¼ä¸é¢çä¸
BasicThread
çå®ä¹ï¼
class BasicThread : public tars::TC_Thread, public tars::TC_ThreadLock
{
...
void terminate()
{
_bTerm = true;
{
Lock lock(*this);
notifyAll();
}
getThreadControl().join();
}
}
å¤å¶
BasicThread
ç±»ï¼ç»§æ¿äº
TC_Thread
å
TC_ThreadLock
ï¼å ¶ä¸
TC_ThreadLock
第äºç¹å·²ç»è¯´æè¿äºï¼æ以è¿ééç¹çä¸
TC_Thread
ç±»ç使ç¨ï¼
TC_Thread
çå®ä¹
class TC_Thread : public TC_Runable
{
...
/**
* 使ç¨äºC++11æ å线ç¨åºstd::thread, æé å½æ°ä¼ åæ°threadEntry线ç¨å½æ°ï¼
* è¿å TC_ThreadControl(_th)ï¼å
¶ä¸_th为std::thread对象
*/
TC_ThreadControl start();
static void threadEntry(TC_Thread *pThread); //éæå½æ°, 线ç¨å
¥å£
virtual void run() = 0;
...
}
å¤å¶
ä¸ä¸æ¥çä¸çº¿ç¨æ§å¶ç±»
TC_ThreadControl
çå®ä¹ï¼
class TC_ThreadControl
{
...
explicit TC_ThreadControl(std::thread *th); // æé ï¼ä¼ å
¥std::thread对象
void join(); // è°ç¨std::threadçjoin()é»å¡å½åç线ç¨ï¼ç´å°å¦å¤ä¸ä¸ªçº¿ç¨è¿è¡ç»æ
static void sleep(); // è°ç¨std::this_thread::sleepå½æ°çº¿ç¨å°æåæ§è¡
...
}
å¤å¶
ä¸ä¸æ¥çä¸
TC_Runable
çå®ä¹ï¼
class TC_Runable
{
public:
virtual ~TC_Runable(){};
virtual void run() = 0; //å®ä¹äºrun纯èå½æ°
};
å¤å¶
æåçä¸å®é 项ç®ä¸å¯¹çº¿ç¨ç±»ç使ç¨
class AntiSdkSyncThread : public BasicThread //è¿éçäºå¤ç»§æ¿äºTC_ThreadåTC_ThreadLock两个类
{
void run() //å®ç°åºç±»ç纯èå½æ°
{
Lock lock(*this);
timedWait(10 * 1000); ï¼é´éæ§è¡æ¶é´ï¼å®ç°äºçº¿ç¨çå®æ¶æ§è¡åè½ï¼
if(NULL != g_busi_interf)
{
Int32 ret = g_busi_interf->proc_(); //éè¦å®ææ§è¡çå½æ°
}
}
}
å¤å¶
å®ä¹å¥½äº
AntiSdkSyncThread g_antiSdkSyncThread;
ç±»ï¼é£ä¹éè¦å¯å¨çº¿ç¨çæ¶åæ§è¡
g_antiSdkSyncThread.start();
å°±ä¼èªç¶å建线ç¨ï¼å¹¶ä¸
threadEntry
线ç¨å½æ°ä¼è°ç¨
pThread->run()
å¤æå½æ°ï¼è¿ç¨éåºçæ¶åè°ç¨
g_antiSdkSyncThread.terminate();
ã
æºè½æéç±»: TC_AutoPtr
è¿éçæºè½æéå¯ä»¥æ¾å¨å®¹å¨ä¸ï¼ä¸çº¿ç¨å®å ¨çæºè½æéï¼CPP11æ ååºç
auto_ptr
æ¯ä¸è½æ¾å¨å®¹å¨ä¸çï¼è²ä¼¼å·²ç»è¢«æ·æ±°äºï¼ç®åå¤æ°ä½¿ç¨CPP11æ ååºç
shared_ptr
ï¼ä¸è¿éè¦ç¼è¯å¨æ¯æCPP11ã
TC_HandleBase
æºè½æéåºç±»çå®ä¹å¦ä¸ï¼ææéè¦æºè½æéçç±»é½éè¦ä»è¯¥å¯¹è±¡ç»§æ¿ï¼å ¶ä¸ä½¿ç¨äºC++11æ ååºä¸ç
<atomic>
è¿è¡åå计æ°ã
class UTIL_DLL_API TC_HandleBase
{
public:
/**
* @brief å¤å¶
*
* @return TC_HandleBase&
*/
TC_HandleBase& operator=(const TC_HandleBase&)
{
return *this;
}
/**
* @brief å¢å 计æ°
*/
void incRef() { ++_atomic; }
/**
* @brief åå°è®¡æ°
*/
void decRef()
{
if((--_atomic) == 0 && !_bNoDelete)
{
_bNoDelete = true;
delete this;
}
}
/**
* @brief è·å计æ°.
*
* @return int 计æ°å¼
*/
int getRef() const { return _atomic; }
/**
* @brief 设置ä¸èªå¨éæ¾.
*
* @param b æ¯å¦èªå¨å é¤,true or false
*/
void setNoDelete(bool b) { _bNoDelete = b; }
protected:
/**
* @brief æé å½æ°
*/
TC_HandleBase() : _atomic(0), _bNoDelete(false)
{
}
/**
* @brief æ·è´æé
*/
TC_HandleBase(const TC_HandleBase&) : _atomic(0), _bNoDelete(false)
{
}
/**
* @brief ææ
*/
virtual ~TC_HandleBase()
{
}
protected:
std::atomic<int> _atomic; // å¼ç¨è®¡æ°
bool _bNoDelete; // æ¯å¦èªå¨å é¤
};
å¤å¶
ä¸ä¸æ¥ç
TC_AutoPtr
æºè½æé模æ¿ç±»ï¼å¯ä»¥æ¾å¨å®¹å¨ä¸ï¼ä¸çº¿ç¨å®å ¨çæºè½æéï¼è¯¥æºè½æééè¿å¼ç¨è®¡æ°å®ç°ï¼å ¶æé å½æ°åææå½æ°å®ä¹å¦ä¸ï¼
template<typename T>
class TC_AutoPtr
{
TC_AutoPtr(T* p = 0)
{
_ptr = p;
if(_ptr)
{
_ptr->incRef(); //æé å½æ° å¼ç¨è®¡ç®å 1
}
}
...
~TC_AutoPtr()
{
if(_ptr)
{
_ptr->decRef(); //ææå½æ° å¼ç¨è®¡ç®å1
}
}
}
å¤å¶
ä¾åï¼å®æ项ç®ä½¿ç¨
struct ConnStruct : public TC_HandleBase{...}
typedef TC_AutoPtr<ConnStruct> ConnStructPtr;
å¤å¶
TC_AutoPtr
æ·è´æé è°ç¨
_ptr->incRef();
è¿é
ptr
为
ConnStruct
ï¼
ConnStruct
继æ¿äº
TC_HandleBase
ï¼çäºè°ç¨äº
TC_HandleBaseT<int>::incRef() {++_atomic;}
å¼ç¨è®¡æ°ååæä½å 1ãææå¼ç¨è®¡æ°ååæä½å1ï¼å½å¼ç¨è®¡æ°åå°å°0æ¶æ ¹æ®è®¾ç½®çå¼å ³æ¯å¦è¦è¿è¡å é¤æ¥å³å®æ¯å¦è§¦ådeleteã
ä¾åï¼è¿æ¯TARS使ç¨å¼æ¥rpcåè°çå ¸åä¾åï¼è¿éåè°ç±»ä½¿ç¨äºæºè½æé
// å®ä¹åè°å½æ°æºè½æéï¼å
¶ä¸SessionCallbackç¶ç±»ç»§æ¿äºTC_HandleBase
typedef TC_AutoPtr<SessionCallback> SessionCallbackPtr;
//å建åè°ç±»SessionCallbackPtrï¼å¹¶ä¼ å
¥åå§ååæ°uin gameidçï¼
SessionCallbackPtr cb = new SessionCallback(iUin, iGameId, iSeqID, iCmd,sSessionID, theServant, current, cs, this);
//å¼æ¥è°ç¨sessionserverè¿ç¨æ¥å£
getSessionPrx()->async_getSession(cb, iUin, iGameId);
å¤å¶
æ¥å£è¿åå®æï¼åè°
SessionCallback::callback_getSession(tars::Int32 ret, const MGComm::SessionValue& retValue)
å½æ°ï¼æ¥æ¶
sessionserver
æ¥å£çè¿åç
SessionValue
ç»æã
å 为
SessionCallbackPtr
使ç¨äºæºè½æéï¼æ以ä¸å¡ä¸éè¦å»æå¨éæ¾åé¢
new
åºæ¥ç
SessionCallbackPtr
ï¼è¿æ¯æ¯è¾æ¹ä¾¿çã
MySQLæä½ç±»: TC_Mysql
TC_Mysqlå°è£ 好çmysqlæä½ç±»ï¼é线ç¨å®å ¨ï¼å¯¹äº insert/update å¯ä»¥ææ´å¥½çå½æ°å°è£ ï¼é²æ¢SQLæ³¨å ¥
使ç¨æ¹å¼ï¼
TC_Mysql mysql;
//åå§åmysqlï¼initæ¶ä¸é¾æ¥ï¼è¯·æ±æ¶èªå¨å»ºç«é¾æ¥ï¼
//æ°æ®åºå¯ä»¥ä¸ºç©ºï¼
//端å£é»è®¤ä¸º3306
mysql.init("192.168.1.2", "pc", "pc@sn", "db_tars_demo");
å¤å¶
é常ç¨ï¼
void init(const TC_DBConf& tcDBConf);
ç´æ¥åå§åæ°æ®åºãä¾å¦ï¼
stDirectMysql.init(_stZoneDirectDBConf);
çä¸
TC_DBConf
çå®ä¹
struct TC_DBConf
{
string _host;
string _user;
string _password;
string _database;
string _charset;
int _port;
int _flag; //客æ·ç«¯æ è¯
TC_DBConf()
: _port(0)
, _flag(0)
{}
/**
* @brief 读åæ°æ®åºé
ç½®.
*
* @param mpParam åæ¾æ°æ®åºé
ç½®çmap
* dbhost: 主æºå°å
* dbuser:ç¨æ·å
* dbpass:å¯ç
* dbname:æ°æ®åºå称
* dbport:端å£
*/
void loadFromMap(const map<string, string> &mpParam)
{
map<string, string> mpTmp = mpParam;
_host = mpTmp["dbhost"];
_user = mpTmp["dbuser"];
_password = mpTmp["dbpass"];
_database = mpTmp["dbname"];
_charset = mpTmp["charset"];
_port = atoi(mpTmp["dbport"].c_str());
_flag = 0;
if(mpTmp["dbport"] == "")
{
_port = 3306;
}
}
};
å¤å¶
//è¿ä¸æ¥çä¸è·åæ°æ®ç使ç¨
TC_Mysql::MysqlData data;
data = mysql.queryRecord("select * from t_app_users");
for(size_t i = 0; i < data.size(); i++)
{
//å¦æä¸åå¨IDå段ï¼åæåºå¼å¸¸
cout << data[i]["ID"] << endl;
}
å¤å¶
æ¥è¯¢åºæ¥çmysqlæ°æ®ç¨
MysqlData
å°è£
class MysqlData
{ ...
vector<map<string, string> >& data();
...
}
å¤å¶
//æå
¥æ°æ®ï¼æå®æ°æ®çç±»åï¼æ°å¼ æ å符串ï¼å¯¹äºå符串ä¼èªå¨è½¬ä¹
map<string, pair<TC_Mysql::FT, string> > m;
m["ID"] = make_pair(TC_Mysql::DB_INT, "2334");
m["USERID"] = make_pair(TC_Mysql::DB_STR, "abcttt");
m["APP"] = make_pair(TC_Mysql::DB_STR, "abcapbbp");
m["LASTTIME"] = make_pair(TC_Mysql::DB_INT, "now()");
mysql.replaceRecord("t_user_logs", m);
å¤å¶
ç½ç»ç»ä»¶
æ´ä¸ªTARSæ ¸å¿å°±æä¾ä¸ä¸ªå¾å®åçç½ç»æ¡æ¶ï¼å æ¬RPCåè½ï¼è¿éåªä»ç»å 个常ç¨çç½ç»ç»ä»¶ã
TC_Socket : å°è£ äºsocketçåºæ¬æ¹æ³
æä¾socketçæä½ç±»ï¼æ¯ætcp/udp socketï¼æ¯ææ¬å°åå¥æ¥åãåä¸ä¸å±TARSå°è£ äº
TC_TCPClient
å
TC_UDPClient
两个类ç¨äºå®é æä½tcpåudpåºç¨ã
使ç¨æ¹å¼ï¼
ä¾å¦ï¼tcp客æ·ç«¯
TC\_TCPClient stRouterClient;
stRouterClient.init(sIP, iPort, iTimeOut); // è¿éä¼ å
¥ipå端å£ç¶åè°ç¨sendRecvè¿è¡æ¶æ¯çæ¶å
Int32 ret = stRouterClient.sendRecv(request.c\_str(), request.length(), recvBuf, iRecvLen);
å¤å¶
注æå¤çº¿ç¨ä½¿ç¨çæ¶åï¼ä¸è½å¤çº¿ç¨åæ¶send/recvï¼å°å¿ä¸²å ã
TC_Epoller
æä¾ç½ç»epollçæä½ç±»ï¼é»è®¤æ¯ET模å¼ï¼å½ç¶æåçååçæ¶åæè·å¾éç¥ï¼æä¾addãmodãdelãwaitçåºç¡æä½ã
TC_ClientSocket : 客æ·ç«¯socketç¸å ³æä½åºç±»
æä¾å ³é®æåå½æ°
init(const string &sIp, int iPort, int iTimeout)
ï¼ä¼ å ¥ IP ç«¯å£ å è¶ æ¶æ¶é´
TC_TCPClient
继æ¿äº
TC_ClientSocket
æä¾æåå½æ°ï¼
-
ï¼åéå°æå¡å¨, ä»æå¡å¨è¿åä¸è¶ è¿iRecvLençåèï¼sendRecv
-
ï¼ åéåæå¡å¨, 并çå¾ æå¡å¨ç´å°ç»å°¾å符, å å«ç»å°¾å符ï¼sendRecvBySep
ä¾åï¼
stRouterClient.init(sIP, iPort, iTimeOut);
size_t iRecvLen = sizeof(recvBuf)-1;
Int32 ret = stRouterClient.sendRecv(request.c_str(), request.length(), recvBuf, iRecvLen);
å¤å¶
åçè¿æ
TC_UDPClient
å®ç°UDP客æ·ç«¯ã
å½ä»¤è§£æç±»: TC_Option
- å½ä»¤è§£æç±»ï¼
- é常ç¨äºè§£æå½ä»¤è¡åæ°ï¼
- åªæ¯æåâçåæ°å½¢å¼
- åæ
çè¾å ¥åæ°ï¼æ¯æ以ä¸å½¢å¼çåæ°ï¼main
./main.exe --name=value --param1 param2 param3
å¤å¶
TC_Option op;
//解æå½ä»¤è¡
op.decode(argc, argv);
//è·åæ对çåæ°ï¼å³è·å - - 表示çææåæ°å¯¹
map<string, string> mp = op.getMulti();
//表示é â çåæ°ï¼å³ param2, param3
vector<string> d = op.getSingle();
å¤å¶
å¦ævalueï¼paramæç©ºæ ¼æè
--
ï¼ç¨å¼å·æ¬èµ·æ¥å°±å¯ä»¥äºã
é ç½®æ件类: TC_Config
- é ç½®æ件解æç±»ï¼å ¼å®¹wbl模å¼ï¼ï¼
- æ¯æä»stringä¸è§£æé ç½®æ件ï¼
- æ¯æçæé ç½®æ件ï¼
- 解æåºéæåºå¼å¸¸ï¼
- éç¨[]è·åé ç½®ï¼å¦ææ é ç½®åæåºå¼å¸¸ï¼
- éç¨getè·åé ç½®ï¼ä¸åå¨åè¿å空ï¼
- 读åé ç½®æ件æ¯çº¿ç¨å®å ¨çï¼insertåçå½æ°é线ç¨å®å ¨
ä¾åï¼
TC_Config config;
config.parseFile(ServerConfig::BasePath + ServerConfig::ServerName + ".conf");
stTmpGameServerConfig.iGameId = TC_Common::strto<UInt32>(config["/Main/<GameId>"]);
å¤å¶
é ç½®æä»¶æ ·ä¾
<Main>
GameId = 3001
ZoneId = 102
AsyncThreadCheckInterval = 1000
...
</Main>
å¤å¶
使ç¨
get
æ¹æ³ä¾åï¼å¦æ读ä¸å°è¯¥é ç½®ï¼åè¿åé»è®¤å¼
sDefault
ï¼å³ä¸é¢ä¾åä¸ç
20000000
stTmpGameServerConfig.iMaxRegNum = TC_Common::strto<Int32>(config.get("/Main/<MaxRegNum>", "20000000"));
å¤å¶
éç¨ä»¿å½æ°ç±»: TC_Functor
TC_Functor
åè
loki
åºç设计
- 仿å½æ°å¯¹è±¡è°ç¨æ¹å¼, å³å¯¹ä¸è¿°çå ç§æ¹å¼é½å¯ä»¥å¨å³ä¾§æ·»å ä¸å¯¹åæ¬å·,并å¨æ¬å·å
é¨æ¾ä¸ç»åéçåæ°æ¥è°ç¨,ä¾å¦
a(p1,p2);
- ææ´ä¸ªè°ç¨(å
æ¬åæ°)å°è£
ä¸ä¸ªå½æ°å¯¹è±¡, è°ç¨å¯¹è±¡å»ºç«æ¶å°±ä¼ å
¥äºåæ°ï¼è°ç¨çæ¶åä¸ç¨ä¼ å
¥åæ°ï¼ä¾å¦
A a(p1, p2); a();
ç®åå好ç¨çå°è£ ï¼å ·ä½è§ä¸é¢ä½¿ç¨ä¾åèªç¶æç½ï¼
Cå½æ°è°ç¨
void TestFunction3(const string &s, int i){
cout << "TestFunction3('" << s << "', '" << i << "')" << endl;
}
//éç¨å½æ°æéæé 对象
TC_Functor<void, TL::TLMaker<const string&, int>::Result > cmd3(TestFunction3);
string s3("s3");
cmd3(s3, 10);
å¤å¶
Cå½æ°è°ç¨ç¨wrapperå°è£ :
//è°ç¨å°è£
ï¼æé çæ¶åä¼ å
¥åæ°
TC_Functor<void,TL::TLMaker<const string&, int>::Result>::wrapper_type fwrapper3(cmd3, s3, 10);
fwrapper3(); //åæ°å·²ç»å¨æé çæ¶åä¼ å
¥ï¼è°ç¨çæ¶åä¸ç¨ä¼ åæ°äº
å¤å¶
说æ:
-
: å½æ°çè¿åå¼void
-
: 代表åæ°ç±»åTL::TLMaker<const string&, int>::Result
对äºè°ç¨çå°è£ ï¼æ³¨æ对äºä¼ å¼ç¨ç±»åï¼å ·ä½çè°ç¨æ¶åè¦ä¿è¯å¼ç¨ç对象åå¨ã
C++æåç±»æåå½æ°çè°ç¨
struct TestMember
{
void mem3(const string &s, int i)
{
cout << "TestMember::mem3(" << s << "," << i << ") called" << endl;
}
}
TC_Functor<void, TL::TLMaker<const string&, int>::Result > cmd3(&tm, &TestMember::mem3);
cmd3("a", 33);
å¤å¶
æåç±»æåå½æ°çè°ç¨ç¨wrapperå°è£ :
TC_Functor<void, TL::TLMaker<const string&, int>::Result >::wrapper_type fwrapper3(cmd3, "a", 10);
fwrapper3();
å¤å¶
å®é ä¾åï¼æ³¨åå议解æå¨
æå¡åå§åinitializeçæ¶åï¼ä¸è¬ä¼è°ç¨
addServantProtocol(sRouterObj, AppProtocol::parseStream<0, uint16_t, false>,iHeaderLen);
å¤å¶
è¿é设置
BindAdapter
çå议解æå½æ°
protocol_functor _pf
为
parseStream
å½æ°ï¼å¦ä¸ï¼
/**
* @param T
* @param offset
* @param netorder
* @param in
* @param out
* @return int
*/
template<size_t offset, typename T, bool netorder>
static TC_NetWorkBuffer::PACKET_TYPE parseStream(TC_NetWorkBuffer& in,vector<char>& out)
{
size_t len = offset + sizeof(T);
if (in.getBufferLength() < len)
{
return TC_NetWorkBuffer::PACKET_LESS;
}
string header;
in.getHeader(len, header);
assert(header.size() == len);
T iHeaderLen = 0;
::memcpy(&iHeaderLen, header.c_str() + offset, sizeof(T));
if (netorder)
{
iHeaderLen = net2host<T>(iHeaderLen);
}
//é¿åº¦ä¿æ¤ä¸ä¸
if (iHeaderLen < (T)(len) || (uint32_t)iHeaderLen > TARS_NET_MAX_PACKAGE_SIZE)
{
return TC_NetWorkBuffer::PACKET_ERR;
}
if (in.getBufferLength() < (uint32_t)iHeaderLen)
{
return TC_NetWorkBuffer::PACKET_LESS;
}
in.getHeader(iHeaderLen, out);
assert(out.size() == iHeaderLen);
in.moveHeader(iHeaderLen);
return TC_NetWorkBuffer::PACKET_FULL;
}
å¤å¶
注å好解æå½æ°ä¹åï¼ç½ç»å±æ¶å è°ç¨
parseProtocol
å½æ°
int TC_EpollServer::Connection::parseProtocol(TC_NetWorkBuffer &rbuf)
{
...
TC_NetWorkBuffer::PACKET_TYPE b = _pBindAdapter->getProtocol()(rbuf, ro); //è¿éåè°åé¢è®¾ç½®å¥½çå议解æå½æ°ï¼ä»èå®ç°å议解æ
...
}
å¤å¶
hashç®æ³
util/tc_hash_fun.h
ä¸å å«äºå¯¹hashç®æ³çå®ç°ï¼ä½¿ç¨
hash_new
ï¼å¯ä»¥å¯¹è¾å ¥çåèæµè¿è¡hashå¾å°ç¸å½ååçhashå¼ï¼ä½¿ç¨æ¹å¼å¦ä¸
#include "util/tc_hash_fun.h"
#include <iterator>
#include <iostream>
#include <sys/time.h>
using namespace tars;
using namespace std;
int main(int argc, char* *argv[])
{
unsigned int i = tars::hash_new<string>()("abcd");
cout << i << endl;
return 0;
}
å¤å¶
å¼å¸¸ç±»: TC_Exception
class TC_Exception : public exception
{
/**
* @brief æé å½æ°,æä¾äºä¸ä¸ªå¯ä»¥ä¼ å
¥errnoçæé å½æ°ï¼
* å¼å¸¸æåºæ¶ç´æ¥è·åçé误信æ¯
*
* @param buffer å¼å¸¸çåè¦ä¿¡æ¯
* @param err é误ç , å¯ç¨strerrorè·åé误信æ¯
*/
TC_Exception(const string &buffer, int err);
}
å¤å¶
æ»ç»
æ¬æä»ç»åæäºTARSæ¡æ¶ä¸ç¨C++å®ç°çå ¬ç¨åºç¡ç»ä»¶ï¼å 深对è¿äºå·¥å ·ç±»åºç¡ç»ä»¶çç解ï¼åå°å¨ä½¿ç¨è¿äºç»ä»¶è¿ç¨ä¸äº§ççé®é¢ï¼æé«å¼åæçã
TARSå¯ä»¥å¨èèå°æç¨æ§åé«æ§è½çåæ¶å¿«éæ建系ç»å¹¶èªå¨çæ代ç ï¼å¸®å©å¼å人ååä¼ä¸ä»¥å¾®æå¡çæ¹å¼å¿«éæ建èªå·±ç¨³å®å¯é çåå¸å¼åºç¨ï¼ä»è令å¼å人ååªå ³æ³¨ä¸å¡é»è¾ï¼æé«è¿è¥æçãå¤è¯è¨ãææ·ç åãé«å¯ç¨åé«æè¿è¥çç¹æ§ä½¿ TARS æ为ä¼ä¸çº§äº§åã
TARSå¾®æå¡å©æ¨æ°åå转åï¼æ¬¢è¿è®¿é®ï¼
TARSå®ç½ï¼https://TarsCloud.org
TARSæºç ï¼https://github.com/TarsCloud
è·åãTARSå®æ¹å¹è®çµå书ãï¼https://wj.qq.com/s2/6570357/3adb/
ææ«ç è·åï¼
QR