【问题标题】:C++ / Gloox: how to check when connection is down?C ++ / Gloox:如何检查连接何时断开?
【发布时间】:2010-08-22 20:39:25
【问题描述】:

我正在尝试在 c++/gloox 上编写自己的 jabber 机器人。一切正常,但是当互联网连接断开时 - bot 认为它仍然连接,并且当连接再次打开时 - 当然 bot 不会响应任何消息。

自 bot 成功连接 gloox'recv() 后每次返回 ConnNoError,即使接口已关闭且电缆已拔出。

尝试使用阻塞和非阻塞 gloox' 连接和 recv() 都没有任何结果。定期检查不同线程中的 xmpp 服务器的可用性似乎不是一个好主意,那么如何正确检查机器人现在是否连接?

如果不能只使用 gloox - 请指出一些好的方法,但让它在 unix 中可用。

【问题讨论】:

    标签: c++ linux unix xmpp


    【解决方案1】:

    我也有同样的问题,找到了recv总是返回ConnNoError的原因。这是我发现的。当连接建立后,recv 调用 ConnectionTCPBase.cpp 中名为 dataAvailable 的函数,该函数返回

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

    搜索谷歌,I found this thread,它说 FD_ISSET(m_socket, &fds) 会检测到套接字是可读的但不是关闭的......即使网络中断,FD_ISSET(m_socket, &fds) 的返回值也始终为 0。在这种情况下,dataAvailable的返回值为false,所以下面的代码最终在recv中返回ConnNoError。

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

    我不知道这是一个错误还是什么,似乎不是。

    后来我尝试了另一种方式,直接写入套接字,如果套接字关闭,这将导致一个SIGPIPE,捕获该信号,然后使用清理断开连接。

    我终于找到了一个优雅的解决方案,使用心跳。

    在 gloox 线程中,调用 heartBeat(),其中 m_pClient 是指向 gloox::Client 实例的指针

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

    xmppPing会将自己注册到eventhandler,当ping回来时会调用handleEvent,并在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;  
    }  
    

    连接服务器,关闭网络,3秒后,我断开了!

    【讨论】:

      【解决方案2】:

      您必须定义 onDisconnect(ConnectionError e) 才能处理断开连接事件。文档地址为http://camaya.net/api/gloox-0.9.9.12/classgloox_1_1ConnectionListener.html#a2

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-02-09
        • 1970-01-01
        • 2010-10-05
        • 1970-01-01
        • 2014-10-05
        • 1970-01-01
        • 2019-06-23
        相关资源
        最近更新 更多