This commit is contained in:
2015-06-03 09:13:36 +02:00
parent aea96607b2
commit 7838113164
@@ -330,31 +330,43 @@ void DeviceRepoHandler::__handleCommand(Poco::Net::HTTPServerRequest &req, Poco:
void DeviceRepoHandler::__handleEventLongPolling(Poco::Net::HTTPServerRequest &req, Poco::Net::HTTPServerResponse &resp, DeviceEventQueue* eventQueue) {
Variant msg;
bool breakLoop = false;
parent->getIOService().post([&]() {
Net::HTTPServerRequestImpl* reqImpl = static_cast<Net::HTTPServerRequestImpl*>(&req);
// I don't like the content of this loop at all.
while (!breakLoop) {
boost::asio::deadline_timer connCheckTimer(parent->getIOService());
Net::HTTPServerRequestImpl* reqImpl = static_cast<Net::HTTPServerRequestImpl*>(&req);
std::mutex _m;
std::function<void(const boost::system::error_code& error)> connCheckFun = [&](const boost::system::error_code& error) {
if (error != boost::asio::error::operation_aborted) {
std::lock_guard<std::mutex> _l(_m);
// How to find out whether the client disconnected: Monitor the socket with Posix "select":
// If select says that there is data, available() returns 0 then apparently the client has disconnected.
// WTF, is this really the only way to notice that a client properly disconnected? Internet says so.
auto sockfs = reqImpl->socket().impl()->sockfd();
fd_set fds;
FD_ZERO(&fds);
FD_SET(sockfs, &fds);
// And don't move anything outside, everything needs to be inside to work
auto sockfs = reqImpl->socket().impl()->sockfd();
fd_set fds;
FD_ZERO(&fds);
FD_SET(sockfs, &fds);
struct timeval timeout = {0, 1000};
int sel = select(sockfs + 1, &fds, 0, 0, &timeout);
std::cout << "Debug03: " << sel << " - " << reqImpl->socket().available() << " - " << sockfs << std::endl;
if (sel < 0 || (sel > 0 && reqImpl->socket().available() == 0)) {
ROS_ERROR_STREAM("Apparently we have a disconnect in device event queue \"" << eventQueue->clientID << "\"");
breakLoop = true;
eventQueue->cancelPopEvent();
}
connCheckTimer.expires_from_now(boost::posix_time::milliseconds(100));
connCheckTimer.async_wait(connCheckFun);
}
});
};
connCheckTimer.expires_from_now(boost::posix_time::milliseconds(100));
connCheckTimer.async_wait(connCheckFun);
try {
msg = eventQueue->popEvent();
} catch (DeviceEventQueue::DisconnectedException& e) {
}
breakLoop = true;
{
std::lock_guard<std::mutex> _l(_m);
breakLoop = true;
connCheckTimer.cancel();
}
handleResponse(req, resp, msg);
};
@@ -579,6 +591,7 @@ libvariant::Variant DeviceEventQueue::popEvent() {
FD_SET(sockfs, &fds);
struct timeval timeout = {0, 1};
int sel = select(sockfs + 1, &fds, 0, 0, &timeout);
std::cout << "Debug01: " << sel << " - " << reqImpl->socket().available() << " - " << sockfs << std::endl;
if (sel > 0 && reqImpl->socket().available() == 0) {
ROS_ERROR_STREAM("Apparently we have a disconnect in device event queue \"" << clientID << "\"");
throw DisconnectedException();