开发者

C++ / Gloox: how to check when connection is down?

I'm trying to write own jabber bot on c++/gloox. Everything goes fine, but when internet connection is down - bot thinks that it's still connected, and when connection is up again - of course bot doesn't respond to any message.

Each time since b开发者_开发技巧ot is successfully connected gloox' recv() returns ConnNoError, even if interface is down and cable unplugged.

Tried use blocking and non-blocking gloox' connection and recv() and all was without any result. Periodic checks of availability of xmpp server in different thread is not seems like a good idea, so how to properly check is bot connected right now or no?

If it's not possible to do with gloox only - please point me on some good method, but let it be availible in unix.


I have the same question, and found the reason why recv always retrun ConnNoError. Here is what I found. When the connection is established, the recv calls a funciton named dataAvailable In ConnectionTCPBase.cpp which return

( ( select( m_socket + 1, &fds, 0, 0, timeout == -1 ? 0 : &tv ) > 0 ) && FD_ISSET( m_socket, &fds ) != 0 )

searching google, I found this thread, it said FD_ISSET( m_socket, &fds ) would detect the socket is readble but not is closed ... Return value of FD_ISSET( m_socket, &fds ) is always 0, even the network is down. In such case, the return value of dataAvailable is false, so the code below finally returns ConnNoError in recv.

if( !dataAvailable( timeout ) )
{
  m_recvMutex.unlock();
  return ConnNoError;
}

I don't know whether it is a bug or what, seems not.

Later I tried another way, write to the socket directly, and this will cause a SIGPIPE if the socket is closed, catch that signal, then use cleanup to disconnect.

I finally figure out a graceful solution to this problem, using heartbeat.

in the gloox thread, call heartBeat(), where m_pClient is an pointer to a instance of gloox::Client

void    CXmpp::heartBeat()
{
    m_pClient->xmppPing(m_pClient->jid(), this);
    if (++heart) > 3) {
        m_pClient->disconnect();
    }
}

xmppPing will register itself to eventhandler, when ping comes back, it will call handleEvent, and in handleEvent

void CEventHandler::handleEvent(const Event& event)  
{  
    std::string sEvent;  
    switch (event.eventType())  
    {  
        case Event::PingPing:   
            sEvent = "PingPing";  
            break;  
        case Event::PingPong:   
            sEvent = "PingPong";  
            //recieve from server, decrease the count of heart
            --heart;  
            break;  
        case Event::PingError:  
            sEvent = "PingError";  
            break;  
        default:  
            break;  
    }  
    return;  
}  

connect to the server, turn off the network, 3 seconds later, I got a disconnect!


You have to define the onDisconnect(ConnectionError e) to be able to handle the disconnect event. The address to documentation is http://camaya.net/api/gloox-0.9.9.12/classgloox_1_1ConnectionListener.html#a2

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜