gpt4 book ai didi

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

转载 作者:太空狗 更新时间:2023-10-29 21:30:02 25 4
gpt4 key购买 nike

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

自从 bot 成功连接后,gloox 的 recv() 每次都会返回 ConnNoError,即使接口(interface)已关闭且电缆已拔出也是如此。

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

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

最佳答案

我也有同样的疑问,找到recv总是retrun 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;
}

不知道是bug还是什么,好像不是。

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

我终于想出了一个优雅的解决方案,使用 heartbeat。

在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秒后,我断开了!

关于C++/Gloox : how to check when connection is down?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3543294/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com