通常在客户端与服务器之间需要心跳来维系连接,XMPP可以通过一个扩展协议
XEP-0199来实现客户端与服务器端的心跳。
封装思路:
在程序中另起一个线程专门用做心跳处理;GLOOX库里对XEP-0199的ping发送实现是在ClientBase类里的一个方法:
void xmpp Ping( const JID &to, EnentHandler *eh );
在说明这个方法之前先介绍GLOOX里面几个相关的类:
ClientBase : 这个类里面用一个方法xmppPing实现XEP-0199 ping消息发送。
EventHandler : ping事件处理器,观察者,纯虚基类。实现其虚函数可以收到Ping响应时得到处理。
EventDispatcher : ping事件分发器,用于注册及注销EventHandler。
Event : ping事件封装类。
方法说明:Sends a XMPP Ping (XEP-0199) to the given JID. 即发送一个符合xep-0199规范的ping消息给指定的JID。我们这里是做对服务器的心跳,所以这里的JID就是服务器的JID;EventHandler是观察者(设计模式之观察者模式),在xmppPing的实现里会将会由EventDispatcher对象将观察者注册进去,在得到事件时将由EventDispatcher将事件分发给观相应的察者处理。所以我们要实现观察者EventHandler.
class CEventHandler:public EventHandler
{
public:
CEventHandler();
virtual ~CEventHandler();
virtual void handleEvent(const Event& event);
void increaceHeartBeatCount(void);
UINT getHeartBeatCount(){return m_nCount;}
private:
void decreaceHeartBeatCount(void);
UINT m_nCount;
};
[cpp]
view plain
copy
class CEventHandler:public EventHandler
{
public:
CEventHandler();
virtual ~CEventHandler();
virtual void handleEvent(const Event& event);
void increaceHeartBeatCount(void);
UINT getHeartBeatCount(){return m_nCount;}
private:
void decreaceHeartBeatCount(void);
UINT m_nCount;
};
[cpp]
view plain
copy
CEventHandler::CEventHandler():m_nCount(0)
{
}
CEventHandler::~CEventHandler()
{
}
void CEventHandler::increaceHeartBeatCount()
{
m_nCount++;
return;
}
void CEventHandler::decreaceHeartBeatCount()
{
if (m_nCount > 0)
{
m_nCount--;
}
return;
}
void CEventHandler::handleEvent(const Event& event)
{
std::string sEvent;
switch (event.eventType())
{
case Event::PingPing: //! 收到PING消息
sEvent = "PingPing";
break;
case Event::PingPong: //! 收到返回PONG消息,心跳累计次数减1
sEvent = "PingPong";
decreaceHeartBeatCount();
break;
case Event::PingError: //!
sEvent = "PingError";
break;
default:
break;
}
TRACE("handleEvent:-------------%s\n", sEvent.c_str());
return;
}
[cpp]
view plain
copy
CEventHandler::CEventHandler():m_nCount(0)
{
}
CEventHandler::~CEventHandler()
{
}
void CEventHandler::increaceHeartBeatCount()
{
m_nCount++;
return;
}
void CEventHandler::decreaceHeartBeatCount()
{
if (m_nCount > 0)
{
m_nCount--;
}
return;
}
void CEventHandler::handleEvent(const Event& event)
{
std::string sEvent;
switch (event.eventType())
{
case Event::PingPing: //! 收到PING消息
sEvent = "PingPing";
break;
case Event::PingPong: //! 收到返回PONG消息,心跳累计次数减1
sEvent = "PingPong";
decreaceHeartBeatCount();
break;
case Event::PingError: //!
sEvent = "PingError";
break;
default:
break;
}
TRACE("handleEvent:-------------%s\n", sEvent.c_str());
return;
}
心跳线程:
[cpp]
view plain
copy
UINT MessageTest::heartBeatThread(LPVOID lpParam)
{
MessageTest* pThis = (MessageTest*)lpParam;
if(NULL == pThis)
return -1;
CEventHandler* pEventHandler = new CEventHandler();
while (!pThis->m_bDisConnect)
{
//! 心跳次数大于三次则通知断链重连,本次心跳线程结束
if (pEventHandler->getHeartBeatCount() > 3)
{
break;
}
pThis->m_client->xmppPing(JID("talk.google.com"), pEventHandler);
pEventHandler->increaceHeartBeatCount();
Sleep(10*1000); //! 发送心跳消息的时间间隔T应由客户端在登录时由服务器返回
}
delete pEventHandler;
TRACE("心跳线程退出\n");
return 0;
}
[cpp]
view plain
copy
UINT MessageTest::heartBeatThread(LPVOID lpParam)
{
MessageTest* pThis = (MessageTest*)lpParam;
if(NULL == pThis)
return -1;
CEventHandler* pEventHandler = new CEventHandler();
while (!pThis->m_bDisConnect)
{
//! 心跳次数大于三次则通知断链重连,本次心跳线程结束
if (pEventHandler->getHeartBeatCount() > 3)
{
break;
}
pThis->m_client->xmppPing(JID("talk.google.com"), pEventHandler);
pEventHandler->increaceHeartBeatCount();
Sleep(10*1000); //! 发送心跳消息的时间间隔T应由客户端在登录时由服务器返回
}
delete pEventHandler;
TRACE("心跳线程退出\n");
return 0;