try to reconnect to nfd when connection is down
Change-Id: I37ac7d6894cf058dc0453dd25425d8e1a6dc4e18
Refs: #2470
diff --git a/src/chat-dialog-backend.cpp b/src/chat-dialog-backend.cpp
index 6cd24ad..bbe17da 100644
--- a/src/chat-dialog-backend.cpp
+++ b/src/chat-dialog-backend.cpp
@@ -6,6 +6,7 @@
* BSD license, See the LICENSE file for more information
*
* Author: Yingdi Yu <yingdi@cs.ucla.edu>
+ * Qiuhan Ding <qiuhanding@cs.ucla.edu>
*/
#include "chat-dialog-backend.hpp"
@@ -28,6 +29,7 @@
static const ndn::Name::Component ROUTING_HINT_SEPARATOR =
ndn::name::Component::fromEscapedString("%F0%2E");
static const int IDENTITY_OFFSET = -3;
+static const int CONNECTION_RETRY_TIMER = 3;
ChatDialogBackend::ChatDialogBackend(const Name& chatroomPrefix,
const Name& userChatPrefix,
@@ -37,6 +39,7 @@
const Name& signingId,
QObject* parent)
: QThread(parent)
+ , m_shouldResume(false)
, m_localRoutingPrefix(routingPrefix)
, m_chatroomPrefix(chatroomPrefix)
, m_userChatPrefix(userChatPrefix)
@@ -63,13 +66,40 @@
if (m_face == nullptr)
break;
- m_face->getIoService().run();
-
+ try {
+ m_face->getIoService().run();
+ }
+ catch (std::runtime_error& e) {
+ {
+ std::lock_guard<std::mutex>lock(m_nfdConnectionMutex);
+ m_isNfdConnected = false;
+ }
+ emit nfdError();
+ {
+ std::lock_guard<std::mutex>lock(m_resumeMutex);
+ m_shouldResume = true;
+ }
+#ifdef BOOST_THREAD_USES_CHRONO
+ time::seconds reconnectTimer = time::seconds(CONNECTION_RETRY_TIMER);
+#else
+ boost::posix_time::time_duration reconnectTimer;
+ reconnectTimer = boost::posix_time::seconds(CONNECTION_RETRY_TIMER);
+#endif
+ while (!m_isNfdConnected) {
+#ifdef BOOST_THREAD_USES_CHRONO
+ boost::this_thread::sleep_for(reconnectTimer);
+#else
+ boost::this_thread::sleep(reconnectTimer);
+#endif
+ }
+ emit refreshChatDialog(m_routableUserChatPrefix);
+ }
{
- std::lock_guard<std::mutex>lock(m_mutex);
+ std::lock_guard<std::mutex>lock(m_resumeMutex);
shouldResume = m_shouldResume;
m_shouldResume = false;
}
+ close();
} while (shouldResume);
@@ -161,13 +191,16 @@
}
void
-ChatDialogBackend::close()
-{
+ChatDialogBackend::exitChatroom() {
if (m_joined)
sendLeave();
usleep(100000);
+}
+void
+ChatDialogBackend::close()
+{
m_scheduler->cancelAllEvents();
m_helloEventId.reset();
m_roster.clear();
@@ -386,6 +419,7 @@
m_helloEventId = m_scheduler->scheduleEvent(HELLO_INTERVAL,
bind(&ChatDialogBackend::sendHello, this));
+ emit newChatroomForDiscovery(Name::Component(m_chatroomName));
}
void
@@ -487,11 +521,11 @@
m_localRoutingPrefix = newLocalRoutingPrefix;
{
- std::lock_guard<std::mutex>lock(m_mutex);
+ std::lock_guard<std::mutex>lock(m_resumeMutex);
m_shouldResume = true;
}
- close();
+ exitChatroom();
updatePrefixes();
@@ -503,15 +537,28 @@
ChatDialogBackend::shutdown()
{
{
- std::lock_guard<std::mutex>lock(m_mutex);
+ std::lock_guard<std::mutex>lock(m_resumeMutex);
m_shouldResume = false;
}
- close();
+ {
+ // In this case, we just stop checking the nfd connection and exit
+ std::lock_guard<std::mutex>lock(m_nfdConnectionMutex);
+ m_isNfdConnected = true;
+ }
+
+ exitChatroom();
m_face->getIoService().stop();
}
+void
+ChatDialogBackend::onNfdReconnect()
+{
+ std::lock_guard<std::mutex>lock(m_nfdConnectionMutex);
+ m_isNfdConnected = true;
+}
+
} // namespace chronochat
#if WAF
diff --git a/src/chat-dialog-backend.hpp b/src/chat-dialog-backend.hpp
index f0fead3..70ebefc 100644
--- a/src/chat-dialog-backend.hpp
+++ b/src/chat-dialog-backend.hpp
@@ -5,6 +5,7 @@
* BSD license, See the LICENSE file for more information
*
* Author: Yingdi Yu <yingdi@cs.ucla.edu>
+ * Qiuhan Ding <qiuhanding@cs.ucla.edu>
*/
#ifndef CHRONOCHAT_CHAT_DIALOG_BACKEND_HPP
@@ -18,6 +19,7 @@
#include "chatbuf.pb.h"
#include <mutex>
#include <socket.hpp>
+#include <boost/thread.hpp>
#endif
namespace chronochat {
@@ -47,7 +49,7 @@
const std::string& chatroomName,
const std::string& nick,
const Name& signingId = Name(),
- QObject* parent = 0);
+ QObject* parent = nullptr);
~ChatDialogBackend();
@@ -63,6 +65,9 @@
loadTrustAnchor();
void
+ exitChatroom();
+
+ void
close();
void
@@ -121,11 +126,20 @@
chatPrefixChanged(ndn::Name newChatPrefix);
void
+ refreshChatDialog(ndn::Name chatPrefix);
+
+ void
eraseInRoster(ndn::Name sessionPrefix, ndn::Name::Component chatroomName);
void
addInRoster(ndn::Name sessionPrefix, ndn::Name::Component chatroomName);
+ void
+ newChatroomForDiscovery(ndn::Name::Component chatroomName);
+
+ void
+ nfdError();
+
public slots:
void
sendChatMessage(QString text, time_t timestamp);
@@ -136,9 +150,14 @@
void
shutdown();
+ void
+ onNfdReconnect();
+
private:
typedef std::map<ndn::Name, UserInfo> BackendRoster;
+ bool m_shouldResume;
+ bool m_isNfdConnected;
shared_ptr<ndn::Face> m_face;
Name m_localRoutingPrefix; // routable local prefix
@@ -160,8 +179,8 @@
BackendRoster m_roster; // User roster
- std::mutex m_mutex;
- bool m_shouldResume;
+ std::mutex m_resumeMutex;
+ std::mutex m_nfdConnectionMutex;
};
} // namespace chronochat
diff --git a/src/chat-dialog.cpp b/src/chat-dialog.cpp
index 1167799..0158496 100644
--- a/src/chat-dialog.cpp
+++ b/src/chat-dialog.cpp
@@ -102,6 +102,9 @@
connect(&m_backend, SIGNAL(chatPrefixChanged(ndn::Name)),
this, SLOT(updateLabels(ndn::Name)));
+ connect(&m_backend, SIGNAL(refreshChatDialog(ndn::Name)),
+ this, SLOT(updateLabels(ndn::Name)));
+
// When frontend gets a message to send, notify backend.
connect(this, SIGNAL(msgToSent(QString, time_t)),
&m_backend, SLOT(sendChatMessage(QString, time_t)));
@@ -351,6 +354,7 @@
appendControlMessage(nick, "enters room", timestamp);
m_rosterModel->setStringList(m_scene->getRosterList());
}
+ fitView();
}
void
diff --git a/src/chatroom-discovery-backend.cpp b/src/chatroom-discovery-backend.cpp
index 0da409d..371a119 100644
--- a/src/chatroom-discovery-backend.cpp
+++ b/src/chatroom-discovery-backend.cpp
@@ -26,16 +26,17 @@
// a count enforced when a manager himself find another one publish chatroom data
static const int MAXIMUM_COUNT = 3;
static const int IDENTITY_OFFSET = -1;
+static const int CONNECTION_RETRY_TIMER = 3;
ChatroomDiscoveryBackend::ChatroomDiscoveryBackend(const Name& routingPrefix,
const Name& identity,
QObject* parent)
: QThread(parent)
+ , m_shouldResume(false)
, m_routingPrefix(routingPrefix)
, m_identity(identity)
, m_randomGenerator(static_cast<unsigned int>(std::time(0)))
, m_rangeUniformRandom(m_randomGenerator, boost::uniform_int<>(500,2000))
- , m_shouldResume(false)
{
m_discoveryPrefix.append("ndn")
.append("broadcast")
@@ -59,13 +60,38 @@
if (m_face == nullptr)
break;
- m_face->getIoService().run();
-
+ try {
+ m_face->getIoService().run();
+ }
+ catch (std::runtime_error& e) {
+ {
+ std::lock_guard<std::mutex>lock(m_nfdConnectionMutex);
+ m_isNfdConnected = false;
+ }
+ emit nfdError();
+ {
+ std::lock_guard<std::mutex>lock(m_resumeMutex);
+ m_shouldResume = true;
+ }
+#ifdef BOOST_THREAD_USES_CHRONO
+ time::seconds reconnectTimer = time::seconds(CONNECTION_RETRY_TIMER);
+#else
+ boost::posix_time::time_duration reconnectTimer = boost::posix_time::seconds(CONNECTION_RETRY_TIMER);
+#endif
+ while (!m_isNfdConnected) {
+#ifdef BOOST_THREAD_USES_CHRONO
+ boost::this_thread::sleep_for(reconnectTimer);
+#else
+ boost::this_thread::sleep(reconnectTimer);
+#endif
+ }
+ }
{
- std::lock_guard<std::mutex>lock(m_mutex);
+ std::lock_guard<std::mutex>lock(m_resumeMutex);
shouldResume = m_shouldResume;
m_shouldResume = false;
}
+ close();
} while (shouldResume);
@@ -275,12 +301,10 @@
updatePrefixes();
{
- std::lock_guard<std::mutex>lock(m_mutex);
+ std::lock_guard<std::mutex>lock(m_resumeMutex);
m_shouldResume = true;
}
- close();
-
m_face->getIoService().stop();
}
}
@@ -341,14 +365,12 @@
sendUpdate(chatroomName);
}
else {
- m_chatroomList[chatroomName].chatroomName = chatroomName.toUri();
- m_chatroomList[chatroomName].info.setName(chatroomName);
- m_chatroomList[chatroomName].info.addParticipant(sessionPrefix);
+ onNewChatroomForDiscovery(chatroomName);
}
}
void
-ChatroomDiscoveryBackend::onNewChatroomForDiscovery(Name::Component chatroomName)
+ChatroomDiscoveryBackend::onNewChatroomForDiscovery(ndn::Name::Component chatroomName)
{
Name newPrefix = m_routableUserDiscoveryPrefix;
newPrefix.append(chatroomName);
@@ -406,12 +428,10 @@
updatePrefixes();
{
- std::lock_guard<std::mutex>lock(m_mutex);
+ std::lock_guard<std::mutex>lock(m_resumeMutex);
m_shouldResume = true;
}
- close();
-
m_face->getIoService().stop();
}
@@ -443,15 +463,25 @@
ChatroomDiscoveryBackend::shutdown()
{
{
- std::lock_guard<std::mutex>lock(m_mutex);
+ std::lock_guard<std::mutex>lock(m_resumeMutex);
m_shouldResume = false;
}
- close();
+ {
+ // In this case, we just stop checking the nfd connection and exit
+ std::lock_guard<std::mutex>lock(m_nfdConnectionMutex);
+ m_isNfdConnected = true;
+ }
m_face->getIoService().stop();
}
+void
+ChatroomDiscoveryBackend::onNfdReconnect()
+{
+ std::lock_guard<std::mutex>lock(m_nfdConnectionMutex);
+ m_isNfdConnected = true;
+}
} // namespace chronochat
diff --git a/src/chatroom-discovery-backend.hpp b/src/chatroom-discovery-backend.hpp
index b3f809f..d6bf843 100644
--- a/src/chatroom-discovery-backend.hpp
+++ b/src/chatroom-discovery-backend.hpp
@@ -16,10 +16,10 @@
#ifndef Q_MOC_RUN
#include "common.hpp"
#include "chatroom-info.hpp"
-#include <ndn-cxx/util/scheduler.hpp>
#include <boost/random.hpp>
#include <mutex>
#include <socket.hpp>
+#include <boost/thread.hpp>
#endif
namespace chronochat {
@@ -55,7 +55,7 @@
public:
ChatroomDiscoveryBackend(const Name& routingPrefix,
const Name& identity,
- QObject* parent = 0);
+ QObject* parent = nullptr);
~ChatroomDiscoveryBackend();
@@ -124,6 +124,9 @@
void
chatroomInfoReady(const ChatroomInfo& info, bool isParticipant);
+ void
+ nfdError();
+
public slots:
/**
@@ -166,7 +169,7 @@
* @param chatroomName the name of chatroom the user join
*/
void
- onNewChatroomForDiscovery(Name::Component chatroomName);
+ onNewChatroomForDiscovery(ndn::Name::Component chatroomName);
/**
* @brief get chatroom info from chat dialog
@@ -204,10 +207,15 @@
void
shutdown();
+ void
+ onNfdReconnect();
+
private:
typedef std::map<ndn::Name::Component, ChatroomInfoBackend> ChatroomList;
+ bool m_shouldResume;
+ bool m_isNfdConnected;
Name m_discoveryPrefix;
Name m_routableUserDiscoveryPrefix;
Name m_routingPrefix;
@@ -224,9 +232,9 @@
shared_ptr<chronosync::Socket> m_sock; // SyncSocket
ChatroomList m_chatroomList;
- std::mutex m_mutex;
+ std::mutex m_resumeMutex;
+ std::mutex m_nfdConnectionMutex;
- bool m_shouldResume;
};
} // namespace chronochat
diff --git a/src/controller-backend.cpp b/src/controller-backend.cpp
index df341c9..496cd9a 100644
--- a/src/controller-backend.cpp
+++ b/src/controller-backend.cpp
@@ -6,6 +6,7 @@
* BSD license, See the LICENSE file for more information
*
* Author: Yingdi Yu <yingdi@cs.ucla.edu>
+ * Qiuhan Ding <qiuhanding@cs.ucla.edu>
*/
#include "controller-backend.hpp"
@@ -32,9 +33,11 @@
static const ndn::Name::Component ROUTING_HINT_SEPARATOR =
ndn::name::Component::fromEscapedString("%F0%2E");
static const int MAXIMUM_REQUEST = 3;
+static const int CONNECTION_RETRY_TIMER = 3;
ControllerBackend::ControllerBackend(QObject* parent)
: QThread(parent)
+ , m_shouldResume(false)
, m_contactManager(m_face)
, m_invitationListenerId(0)
{
@@ -54,10 +57,42 @@
void
ControllerBackend::run()
{
- setInvitationListener();
-
- m_face.processEvents();
-
+ bool shouldResume = false;
+ do {
+ try {
+ setInvitationListener();
+ m_face.processEvents();
+ }
+ catch (std::runtime_error& e) {
+ {
+ std::lock_guard<std::mutex>lock(m_nfdConnectionMutex);
+ m_isNfdConnected = false;
+ }
+ emit nfdError();
+ {
+ std::lock_guard<std::mutex>lock(m_resumeMutex);
+ m_shouldResume = true;
+ }
+#ifdef BOOST_THREAD_USES_CHRONO
+ time::seconds reconnectTimer = time::seconds(CONNECTION_RETRY_TIMER);
+#else
+ boost::posix_time::time_duration reconnectTimer;
+ reconnectTimer = boost::posix_time::seconds(CONNECTION_RETRY_TIMER);
+#endif
+ while (!m_isNfdConnected) {
+#ifdef BOOST_THREAD_USES_CHRONO
+ boost::this_thread::sleep_for(reconnectTimer);
+#else
+ boost::this_thread::sleep(reconnectTimer);
+#endif
+ }
+ }
+ {
+ std::lock_guard<std::mutex>lock(m_resumeMutex);
+ shouldResume = m_shouldResume;
+ m_shouldResume = false;
+ }
+ } while (shouldResume);
std::cerr << "Bye!" << std::endl;
}
@@ -318,6 +353,15 @@
void
ControllerBackend::shutdown()
{
+ {
+ std::lock_guard<std::mutex>lock(m_resumeMutex);
+ m_shouldResume = false;
+ }
+ {
+ // In this case, we just stop checking the nfd connection and exit
+ std::lock_guard<std::mutex>lock(m_nfdConnectionMutex);
+ m_isNfdConnected = true;
+ }
m_face.getIoService().stop();
}
@@ -463,6 +507,13 @@
}
+void
+ControllerBackend::onNfdReconnect()
+{
+ std::lock_guard<std::mutex>lock(m_nfdConnectionMutex);
+ m_isNfdConnected = true;
+}
+
} // namespace chronochat
diff --git a/src/controller-backend.hpp b/src/controller-backend.hpp
index d7bda46..78865ef 100644
--- a/src/controller-backend.hpp
+++ b/src/controller-backend.hpp
@@ -5,6 +5,7 @@
* BSD license, See the LICENSE file for more information
*
* Author: Yingdi Yu <yingdi@cs.ucla.edu>
+ * Qiuhan Ding <qiuhanding@cs.ucla.edu>
*/
#ifndef CHRONOCHAT_CONTROLLER_BACKEND_HPP
@@ -22,6 +23,8 @@
#include "validator-invitation.hpp"
#include <ndn-cxx/security/key-chain.hpp>
#include <ndn-cxx/util/in-memory-storage-persistent.hpp>
+#include <boost/thread.hpp>
+#include <mutex>
#endif
namespace chronochat {
@@ -31,7 +34,7 @@
Q_OBJECT
public:
- ControllerBackend(QObject* parent = 0);
+ ControllerBackend(QObject* parent = nullptr);
~ControllerBackend();
@@ -113,6 +116,9 @@
void
invitationRequestResult(const std::string& msg);
+ void
+ nfdError();
+
public slots:
void
shutdown();
@@ -138,11 +144,16 @@
void
onSendInvitationRequest(const QString& chatroomName, const QString& prefix);
+ void
+ onNfdReconnect();
+
private slots:
void
onContactIdListReady(const QStringList& list);
private:
+ bool m_isNfdConnected;
+ bool m_shouldResume;
ndn::Face m_face;
Name m_identity; //TODO: set/get
@@ -164,6 +175,8 @@
QStringList m_chatDialogList;
QMutex m_mutex;
+ std::mutex m_resumeMutex;
+ std::mutex m_nfdConnectionMutex;
ndn::util::InMemoryStoragePersistent m_ims;
};
diff --git a/src/controller.cpp b/src/controller.cpp
index b660597..6121f2b 100644
--- a/src/controller.cpp
+++ b/src/controller.cpp
@@ -6,6 +6,7 @@
* BSD license, See the LICENSE file for more information
*
* Author: Yingdi Yu <yingdi@cs.ucla.edu>
+ * Qiuhan Ding <qiuhanding@cs.ucla.edu>
*/
#include <QApplication>
@@ -44,6 +45,7 @@
Controller::Controller(QWidget* parent)
: QDialog(parent)
, m_localPrefixDetected(false)
+ , m_isInConnectionDetection(false)
, m_settingDialog(new SettingDialog(this))
, m_startChatDialog(new StartChatDialog(this))
, m_profileEditor(new ProfileEditor(this))
@@ -156,6 +158,10 @@
const QString&, bool)));
// Connection to backend thread
+ connect(&m_backend, SIGNAL(nfdError()),
+ this, SLOT(onNfdError()));
+ connect(this, SIGNAL(nfdReconnect()),
+ &m_backend, SLOT(onNfdReconnect()));
connect(this, SIGNAL(shutdownBackend()),
&m_backend, SLOT(shutdown()));
connect(this, SIGNAL(updateLocalPrefix()),
@@ -203,8 +209,6 @@
m_chatroomDiscoveryBackend, SLOT(updateRoutingPrefix(const QString&)));
connect(this, SIGNAL(localPrefixConfigured(const QString&)),
m_chatroomDiscoveryBackend, SLOT(updateRoutingPrefix(const QString&)));
- connect(this, SIGNAL(newChatroomForDiscovery(Name::Component)),
- m_chatroomDiscoveryBackend, SLOT(onNewChatroomForDiscovery(Name::Component)));
connect(m_chatroomDiscoveryBackend, SIGNAL(chatroomInfoRequest(std::string, bool)),
this, SLOT(onChatroomInfoRequest(std::string, bool)));
connect(this, SIGNAL(respondChatroomInfoRequest(ChatroomInfo, bool)),
@@ -213,6 +217,10 @@
m_chatroomDiscoveryBackend, SLOT(shutdown()));
connect(this, SIGNAL(identityUpdated(const QString&)),
m_chatroomDiscoveryBackend, SLOT(onIdentityUpdated(const QString&)));
+ connect(this, SIGNAL(nfdReconnect()),
+ m_chatroomDiscoveryBackend, SLOT(onNfdReconnect()));
+ connect(m_chatroomDiscoveryBackend, SIGNAL(nfdError()),
+ this, SLOT(onNfdError()));
// connect chatroom discovery back end with front end
connect(m_discoveryPanel, SIGNAL(waitForChatroomInfo(const QString&)),
@@ -489,8 +497,14 @@
chatDialog->getBackend(), SLOT(updateRoutingPrefix(const QString&)));
connect(this, SIGNAL(localPrefixConfigured(const QString&)),
chatDialog->getBackend(), SLOT(updateRoutingPrefix(const QString&)));
+ connect(this, SIGNAL(nfdReconnect()),
+ chatDialog->getBackend(), SLOT(onNfdReconnect()));
// connect chat dialog with discovery backend
+ connect(chatDialog->getBackend(), SIGNAL(nfdError()),
+ this, SLOT(onNfdError()));
+ connect(chatDialog->getBackend(), SIGNAL(newChatroomForDiscovery(ndn::Name::Component)),
+ m_chatroomDiscoveryBackend, SLOT(onNewChatroomForDiscovery(ndn::Name::Component)));
connect(chatDialog->getBackend(), SIGNAL(addInRoster(ndn::Name, ndn::Name::Component)),
m_chatroomDiscoveryBackend, SLOT(onAddInRoster(ndn::Name, ndn::Name::Component)));
connect(chatDialog->getBackend(), SIGNAL(eraseInRoster(ndn::Name, ndn::Name::Component)),
@@ -508,7 +522,6 @@
chatDialog, SLOT(shutdown()));
updateMenu();
- emit newChatroomForDiscovery(Name::Component(chatroomName.toStdString()));
}
void
@@ -670,6 +683,11 @@
m_backend.wait();
}
+ if (m_nfdConnectionChecker != nullptr && m_nfdConnectionChecker->isRunning()) {
+ emit shutdownNfdChecker();
+ m_nfdConnectionChecker->wait();
+ }
+
QApplication::quit();
}
@@ -773,10 +791,34 @@
}
void
-Controller::onError(const QString& msg)
+Controller::onNfdError()
{
- QMessageBox::critical(this, tr("ChronoChat"), msg, QMessageBox::Ok);
- exit(1);
+ if (m_isInConnectionDetection)
+ return;
+ // begin a thread
+
+ m_isInConnectionDetection = true;
+ m_nfdConnectionChecker = new NfdConnectionChecker(this);
+
+ connect(m_nfdConnectionChecker, SIGNAL(nfdConnected()),
+ this, SLOT(onNfdReconnect()));
+ connect(this, SIGNAL(shutdownNfdChecker()),
+ m_nfdConnectionChecker, SLOT(shutdown()));
+
+ m_nfdConnectionChecker->start();
+ QMessageBox::information(this, tr("ChronoChat"), "Nfd is not running");
+}
+
+void
+Controller::onNfdReconnect()
+{
+ if (m_nfdConnectionChecker != nullptr && m_nfdConnectionChecker->isRunning()) {
+ m_nfdConnectionChecker->wait();
+ }
+ delete m_nfdConnectionChecker;
+ m_nfdConnectionChecker = nullptr;
+ m_isInConnectionDetection = false;
+ emit nfdReconnect();
}
void
diff --git a/src/controller.hpp b/src/controller.hpp
index fdce4cd..ca92c82 100644
--- a/src/controller.hpp
+++ b/src/controller.hpp
@@ -6,6 +6,7 @@
* BSD license, See the LICENSE file for more information
*
* Author: Yingdi Yu <yingdi@cs.ucla.edu>
+ * Qiuhan Ding <qiuhanding@cs.ucla.edu>
*/
#ifndef CHRONOCHAT_CONTROLLER_HPP
@@ -27,6 +28,7 @@
#include "chat-dialog.hpp"
#include "chatroom-discovery-backend.hpp"
#include "discovery-panel.hpp"
+#include "nfd-connection-checker.hpp"
#ifndef Q_MOC_RUN
#include "common.hpp"
@@ -41,7 +43,7 @@
Q_OBJECT
public: // public methods
- Controller(QWidget* parent = 0);
+ Controller(QWidget* parent = nullptr);
virtual
~Controller();
@@ -119,10 +121,13 @@
removeChatroom(QString chatroomName);
void
- newChatroomForDiscovery(Name::Component chatroomName);
+ respondChatroomInfoRequest(ChatroomInfo chatroomInfo, bool isManager);
void
- respondChatroomInfoRequest(ChatroomInfo chatroomInfo, bool isManager);
+ nfdReconnect();
+
+ void
+ shutdownNfdChecker();
private slots:
void
@@ -186,7 +191,10 @@
onWarning(const QString& msg);
void
- onError(const QString& msg);
+ onNfdError();
+
+ void
+ onNfdReconnect();
void
onChatroomInfoRequest(std::string chatroomName, bool isManager);
@@ -198,6 +206,7 @@
// Communication
Name m_localPrefix;
bool m_localPrefixDetected;
+ bool m_isInConnectionDetection;
// Tray
QAction* m_startChatroom;
@@ -227,7 +236,6 @@
AddContactPanel* m_addContactPanel;
ChatDialogList m_chatDialogList;
DiscoveryPanel* m_discoveryPanel;
- ChatroomDiscoveryBackend* m_chatroomDiscoveryBackend;
// Conf
Name m_identity;
@@ -235,7 +243,9 @@
QSqlDatabase m_db;
// Backend
- ControllerBackend m_backend;
+ ControllerBackend m_backend;
+ ChatroomDiscoveryBackend* m_chatroomDiscoveryBackend;
+ NfdConnectionChecker* m_nfdConnectionChecker;
};
} // namespace chronochat
diff --git a/src/discovery-panel.cpp b/src/discovery-panel.cpp
index aa91028..b7c0ed6 100644
--- a/src/discovery-panel.cpp
+++ b/src/discovery-panel.cpp
@@ -98,7 +98,6 @@
DiscoveryPanel::onChatroomListReady(const QStringList& list)
{
m_chatroomList = list;
- resetPanel();
m_chatroomListModel->setStringList(m_chatroomList);
}
diff --git a/src/nfd-connection-checker.cpp b/src/nfd-connection-checker.cpp
new file mode 100644
index 0000000..023c0b2
--- /dev/null
+++ b/src/nfd-connection-checker.cpp
@@ -0,0 +1,76 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2013, Regents of the University of California
+ *
+ * BSD license, See the LICENSE file for more information
+ *
+ * Author: Qiuhan Ding <qiuhanding@cs.ucla.edu>
+ */
+
+#include "nfd-connection-checker.hpp"
+
+#ifndef Q_MOC_RUN
+
+#endif
+
+namespace chronochat {
+
+static const int CONNECTION_RETRY_TIMER = 2;
+
+NfdConnectionChecker::NfdConnectionChecker(QObject* parent)
+ :QThread(parent)
+{
+}
+
+void
+NfdConnectionChecker::run()
+{
+ m_face = unique_ptr<ndn::Face>(new ndn::Face);
+#ifdef BOOST_THREAD_USES_CHRONO
+ time::seconds reconnetTimer = time::seconds(CONNECTION_RETRY_TIMER);
+#else
+ boost::posix_time::time_duration reconnectTimer;
+ reconnectTimer = boost::posix_time::seconds(CONNECTION_RETRY_TIMER);
+#endif
+ do {
+ {
+ std::lock_guard<std::mutex>lock(m_nfdMutex);
+ m_nfdConnected = true;
+ }
+ try {
+ m_face->expressInterest(Interest("/localhost/nfd/status"),
+ [&] (const Interest& interest, const Data& data) {
+ m_face->shutdown();
+ },
+ [] (const Interest& interest) {});
+ m_face->processEvents(time::milliseconds::zero(), true);
+ }
+ catch (std::runtime_error& e) {
+ {
+ std::lock_guard<std::mutex>lock(m_nfdMutex);
+ m_nfdConnected = false;
+ }
+#ifdef BOOST_THREAD_USES_CHRONO
+ boost::this_thread::sleep_for(reconnetTimer);
+#else
+ boost::this_thread::sleep(reconnectTimer);
+#endif
+ }
+ } while (!m_nfdConnected);
+ emit nfdConnected();
+}
+
+void
+NfdConnectionChecker::shutdown()
+{
+ // In this case, we just stop checking the nfd connection and exit
+ std::lock_guard<std::mutex>lock(m_nfdMutex);
+ m_nfdConnected = true;
+}
+
+} // namespace chronochat
+
+#if WAF
+#include "nfd-connection-checker.moc"
+// #include "nfd-connection-checker.cpp.moc"
+#endif
diff --git a/src/nfd-connection-checker.hpp b/src/nfd-connection-checker.hpp
new file mode 100644
index 0000000..08b6085
--- /dev/null
+++ b/src/nfd-connection-checker.hpp
@@ -0,0 +1,52 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2013, Regents of the University of California
+ *
+ * BSD license, See the LICENSE file for more information
+ *
+ * Author: Qiuhan Ding <qiuhanding@cs.ucla.edu>
+ */
+
+#ifndef CHRONOCHAT_NFD_CONNECTION_CHECKER_HPP
+#define CHRONOCHAT_NFD_CONNECTION_CHECKER_HPP
+
+#include <QThread>
+
+#ifndef Q_MOC_RUN
+#include "common.hpp"
+#include <mutex>
+#include <boost/thread.hpp>
+#include <ndn-cxx/face.hpp>
+#endif
+
+namespace chronochat {
+
+class NfdConnectionChecker : public QThread
+{
+ Q_OBJECT
+
+public:
+ NfdConnectionChecker(QObject* parent = nullptr);
+
+protected:
+ void
+ run();
+
+signals:
+ void
+ nfdConnected();
+
+public slots:
+ void
+ shutdown();
+
+private:
+ bool m_nfdConnected;
+ std::mutex m_nfdMutex;
+
+ unique_ptr<ndn::Face> m_face;
+};
+
+} // namespace chronochat
+
+#endif // CHRONOCHAT_NFD_CONNECTION_CHECKER_HPP