我正在尝试在c / gloox上编写自己的jabber bot.一切正常,但是当Internet连接断开时-bot认为它仍处于连接状态,而当连接再次恢复时-当然bot不响应任何消息.
自从机器人成功连接以来,即使接口关闭并且电缆已拔出,gloox的recv()每次都会返回ConnNoError.
尝试使用阻塞和非阻塞gloox的连接和recv(),但都没有任何结果.定期检查xmpp服务器在不同线程中的可用性似乎不是一个好主意,因此如何正确检查bot是现在连接还是不连接?
如果仅使用gloox是不可能的-请为我指出一些好的方法,但请在Unix中使用它.
解决方法:
我有同样的问题,并找到了recv总是重新运行ConnNoError的原因.这是我发现的.建立连接后,recv将调用一个名为dataAvailable的函数,该函数在ConnectionTCPBase.cpp中返回
( ( select( m_socket + 1, &fds, 0, 0, timeout == -1 ? 0 : &tv ) > 0 ) && FD_ISSET( m_socket, &fds ) != 0 )
在Google搜索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将自己注册到事件处理程序,当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;
}
连接到服务器,关闭网络,三秒钟后,我断开了连接!
标签:unix,xmpp,linux,c-4 来源: https://codeday.me/bug/20191209/2097072.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。