immediately ping the ICE DS every 25ms

This commit is contained in:
Stephen Birarda 2015-05-28 13:17:48 -07:00
parent 81c23e9ca0
commit eb6b80133b
6 changed files with 60 additions and 17 deletions

View file

@ -31,12 +31,13 @@ DomainHandler::DomainHandler(QObject* parent) :
_iceDomainID(), _iceDomainID(),
_iceClientID(), _iceClientID(),
_iceServerSockAddr(), _iceServerSockAddr(),
_icePeer(), _icePeer(this),
_isConnected(false), _isConnected(false),
_settingsObject(), _settingsObject(),
_failedSettingsRequests(0) _failedSettingsRequests(0)
{ {
// if we get a socket that make sure our NetworkPeer ping timer stops
connect(this, &DomainHandler::completedSocketDiscovery, &_icePeer, &NetworkPeer::stopPingTimer);
} }
void DomainHandler::clearConnectionInfo() { void DomainHandler::clearConnectionInfo() {
@ -309,6 +310,10 @@ void DomainHandler::processICEResponsePacket(const QByteArray& icePacket) {
qCDebug(networking) << "Received network peer object for domain -" << packetPeer; qCDebug(networking) << "Received network peer object for domain -" << packetPeer;
_icePeer = packetPeer; _icePeer = packetPeer;
emit requestICEConnectionAttempt(); // ask the peer object to start its ping timer
_icePeer.startPingTimer();
// emit our signal so the NodeList knows to send a ping immediately
emit icePeerSocketsReceived();
} }
} }

View file

@ -99,7 +99,7 @@ signals:
void disconnectedFromDomain(); void disconnectedFromDomain();
void iceSocketAndIDReceived(); void iceSocketAndIDReceived();
void requestICEConnectionAttempt(); void icePeerSocketsReceived();
void settingsReceived(const QJsonObject& domainSettingsObject); void settingsReceived(const QJsonObject& domainSettingsObject);
void settingsReceiveFail(); void settingsReceiveFail();

View file

@ -17,7 +17,8 @@
#include "NetworkPeer.h" #include "NetworkPeer.h"
#include "BandwidthRecorder.h" #include "BandwidthRecorder.h"
NetworkPeer::NetworkPeer() : NetworkPeer::NetworkPeer(QObject* parent) :
QObject(parent),
_uuid(), _uuid(),
_publicSocket(), _publicSocket(),
_localSocket(), _localSocket(),
@ -66,6 +67,18 @@ void NetworkPeer::swap(NetworkPeer& otherPeer) {
swap(_connectionAttempts, otherPeer._connectionAttempts); swap(_connectionAttempts, otherPeer._connectionAttempts);
} }
void NetworkPeer::softReset() {
// a soft reset should clear the sockets and reset the number of connection attempts
_localSocket.clear();
_publicSocket.clear();
// stop our ping timer since we don't have sockets to ping anymore anyways
stopPingTimer();
_connectionAttempts = 0;
}
QByteArray NetworkPeer::toByteArray() const { QByteArray NetworkPeer::toByteArray() const {
QByteArray peerByteArray; QByteArray peerByteArray;

View file

@ -28,7 +28,7 @@ const int UDP_PUNCH_PING_INTERVAL_MS = 25;
class NetworkPeer : public QObject { class NetworkPeer : public QObject {
Q_OBJECT Q_OBJECT
public: public:
NetworkPeer(); NetworkPeer(QObject* parent = 0);
NetworkPeer(const QUuid& uuid, const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket); NetworkPeer(const QUuid& uuid, const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket);
// privatize copy and assignment operator to disallow peer copying // privatize copy and assignment operator to disallow peer copying
@ -36,11 +36,12 @@ public:
NetworkPeer& operator=(const NetworkPeer& otherPeer); NetworkPeer& operator=(const NetworkPeer& otherPeer);
bool isNull() const { return _uuid.isNull(); } bool isNull() const { return _uuid.isNull(); }
bool hasSockets() const { return !_localSocket.isNull() && !_publicSocket.isNull(); }
const QUuid& getUUID() const { return _uuid; } const QUuid& getUUID() const { return _uuid; }
void setUUID(const QUuid& uuid) { _uuid = uuid; } void setUUID(const QUuid& uuid) { _uuid = uuid; }
void reset(); void softReset();
const HifiSockAddr& getPublicSocket() const { return _publicSocket; } const HifiSockAddr& getPublicSocket() const { return _publicSocket; }
virtual void setPublicSocket(const HifiSockAddr& publicSocket) { _publicSocket = publicSocket; } virtual void setPublicSocket(const HifiSockAddr& publicSocket) { _publicSocket = publicSocket; }
@ -65,11 +66,11 @@ public:
float getOutboundBandwidth(); // in kbps float getOutboundBandwidth(); // in kbps
float getInboundBandwidth(); // in kbps float getInboundBandwidth(); // in kbps
void startPingTimer();
void stopPingTimer();
friend QDataStream& operator<<(QDataStream& out, const NetworkPeer& peer); friend QDataStream& operator<<(QDataStream& out, const NetworkPeer& peer);
friend QDataStream& operator>>(QDataStream& in, NetworkPeer& peer); friend QDataStream& operator>>(QDataStream& in, NetworkPeer& peer);
public slots:
void startPingTimer();
void stopPingTimer();
signals: signals:
void pingTimerTimeout(); void pingTimerTimeout();
protected: protected:

View file

@ -73,8 +73,11 @@ NodeList::NodeList(char newOwnerType, unsigned short socketListenPort, unsigned
// send an ICE heartbeat as soon as we get ice server information // send an ICE heartbeat as soon as we get ice server information
connect(&_domainHandler, &DomainHandler::iceSocketAndIDReceived, this, &NodeList::handleICEConnectionToDomainServer); connect(&_domainHandler, &DomainHandler::iceSocketAndIDReceived, this, &NodeList::handleICEConnectionToDomainServer);
// handle ICE signal from DS so connection is attempted immediately // handle ping timeout from DomainHandler to establish a connection with auto networked domain-server
connect(&_domainHandler, &DomainHandler::requestICEConnectionAttempt, this, &NodeList::handleICEConnectionToDomainServer); connect(&_domainHandler.getICEPeer(), &NetworkPeer::pingTimerTimeout, this, &NodeList::pingPunchForDomainServer);
// send a ping punch immediately
connect(&_domainHandler, &DomainHandler::icePeerSocketsReceived, this, &NodeList::pingPunchForDomainServer);
// clear out NodeList when login is finished // clear out NodeList when login is finished
connect(&AccountManager::getInstance(), &AccountManager::loginComplete , this, &NodeList::reset); connect(&AccountManager::getInstance(), &AccountManager::loginComplete , this, &NodeList::reset);
@ -299,6 +302,7 @@ void NodeList::sendDomainServerCheckIn() {
// we don't know our public socket and we need to send it to the domain server // we don't know our public socket and we need to send it to the domain server
qCDebug(networking) << "Waiting for inital public socket from STUN. Will not send domain-server check in."; qCDebug(networking) << "Waiting for inital public socket from STUN. Will not send domain-server check in.";
} else if (_domainHandler.getIP().isNull() && _domainHandler.requiresICE()) { } else if (_domainHandler.getIP().isNull() && _domainHandler.requiresICE()) {
qCDebug(networking) << "Waiting for ICE discovered domain-server socket. Will not send domain-server check in.";
handleICEConnectionToDomainServer(); handleICEConnectionToDomainServer();
} else if (!_domainHandler.getIP().isNull()) { } else if (!_domainHandler.getIP().isNull()) {
bool isUsingDTLS = false; bool isUsingDTLS = false;
@ -472,8 +476,9 @@ void NodeList::handleDSPathQueryResponse(const QByteArray& packet) {
} }
void NodeList::handleICEConnectionToDomainServer() { void NodeList::handleICEConnectionToDomainServer() {
if (_domainHandler.getICEPeer().isNull() // if we're still waiting to get sockets we want to ping for the domain-server
|| _domainHandler.getICEPeer().getConnectionAttempts() >= MAX_ICE_CONNECTION_ATTEMPTS) { // then send another heartbeat now
if (!_domainHandler.getICEPeer().hasSockets()) {
_domainHandler.getICEPeer().resetConnectionAttempts(); _domainHandler.getICEPeer().resetConnectionAttempts();
@ -482,7 +487,24 @@ void NodeList::handleICEConnectionToDomainServer() {
LimitedNodeList::sendHeartbeatToIceServer(_domainHandler.getICEServerSockAddr(), LimitedNodeList::sendHeartbeatToIceServer(_domainHandler.getICEServerSockAddr(),
_domainHandler.getICEClientID(), _domainHandler.getICEClientID(),
_domainHandler.getICEDomainID()); _domainHandler.getICEDomainID());
} else { }
}
void NodeList::pingPunchForDomainServer() {
// make sure if we're here that we actually still need to ping the domain-server
if (_domainHandler.getIP().isNull() && _domainHandler.getICEPeer().hasSockets()) {
// check if we've hit the number of pings we'll send to the DS before we consider it a fail
const int NUM_DOMAIN_SERVER_PINGS_BEFORE_RESET = 2000 / UDP_PUNCH_PING_INTERVAL_MS;
if (_domainHandler.getICEPeer().getConnectionAttempts() > 0
&& _domainHandler.getICEPeer().getConnectionAttempts() % NUM_DOMAIN_SERVER_PINGS_BEFORE_RESET == 0) {
// if we have then nullify the domain handler's network peer and send a fresh ICE heartbeat
_domainHandler.getICEPeer().softReset();
handleICEConnectionToDomainServer();
}
qCDebug(networking) << "Sending ping packets to establish connectivity with domain-server with ID" qCDebug(networking) << "Sending ping packets to establish connectivity with domain-server with ID"
<< uuidStringWithoutCurlyBraces(_domainHandler.getICEDomainID()); << uuidStringWithoutCurlyBraces(_domainHandler.getICEDomainID());
@ -624,7 +646,7 @@ void NodeList::startNodeHolePunch(const SharedNodePointer& node) {
void NodeList::handleNodePingTimeout() { void NodeList::handleNodePingTimeout() {
SharedNodePointer senderNode = nodeWithUUID(qobject_cast<Node*>(sender())->getUUID()); SharedNodePointer senderNode = nodeWithUUID(qobject_cast<Node*>(sender())->getUUID());
if (senderNode) { if (senderNode && !senderNode->getActiveSocket()) {
pingPunchForInactiveNode(senderNode); pingPunchForInactiveNode(senderNode);
} }
} }

View file

@ -64,7 +64,6 @@ public:
void setAssignmentServerSocket(const HifiSockAddr& serverSocket) { _assignmentServerSocket = serverSocket; } void setAssignmentServerSocket(const HifiSockAddr& serverSocket) { _assignmentServerSocket = serverSocket; }
void sendAssignment(Assignment& assignment); void sendAssignment(Assignment& assignment);
void pingPunchForInactiveNode(const SharedNodePointer& node);
public slots: public slots:
void reset(); void reset();
void sendDomainServerCheckIn(); void sendDomainServerCheckIn();
@ -77,6 +76,8 @@ private slots:
void startNodeHolePunch(const SharedNodePointer& node); void startNodeHolePunch(const SharedNodePointer& node);
void handleNodePingTimeout(); void handleNodePingTimeout();
void pingPunchForDomainServer();
private: private:
NodeList() : LimitedNodeList(0, 0) { assert(false); } // Not implemented, needed for DependencyManager templates compile NodeList() : LimitedNodeList(0, 0) { assert(false); } // Not implemented, needed for DependencyManager templates compile
NodeList(char ownerType, unsigned short socketListenPort = 0, unsigned short dtlsListenPort = 0); NodeList(char ownerType, unsigned short socketListenPort = 0, unsigned short dtlsListenPort = 0);
@ -96,6 +97,7 @@ private:
void processDomainServerAddedNode(const QByteArray& packet); void processDomainServerAddedNode(const QByteArray& packet);
void parseNodeFromPacketStream(QDataStream& packetStream); void parseNodeFromPacketStream(QDataStream& packetStream);
void pingPunchForInactiveNode(const SharedNodePointer& node);
NodeType_t _ownerType; NodeType_t _ownerType;
NodeSet _nodeTypesOfInterest; NodeSet _nodeTypesOfInterest;