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(),
_iceClientID(),
_iceServerSockAddr(),
_icePeer(),
_icePeer(this),
_isConnected(false),
_settingsObject(),
_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() {
@ -309,6 +310,10 @@ void DomainHandler::processICEResponsePacket(const QByteArray& icePacket) {
qCDebug(networking) << "Received network peer object for domain -" << 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 iceSocketAndIDReceived();
void requestICEConnectionAttempt();
void icePeerSocketsReceived();
void settingsReceived(const QJsonObject& domainSettingsObject);
void settingsReceiveFail();

View file

@ -17,7 +17,8 @@
#include "NetworkPeer.h"
#include "BandwidthRecorder.h"
NetworkPeer::NetworkPeer() :
NetworkPeer::NetworkPeer(QObject* parent) :
QObject(parent),
_uuid(),
_publicSocket(),
_localSocket(),
@ -66,6 +67,18 @@ void NetworkPeer::swap(NetworkPeer& otherPeer) {
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 peerByteArray;

View file

@ -28,7 +28,7 @@ const int UDP_PUNCH_PING_INTERVAL_MS = 25;
class NetworkPeer : public QObject {
Q_OBJECT
public:
NetworkPeer();
NetworkPeer(QObject* parent = 0);
NetworkPeer(const QUuid& uuid, const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket);
// privatize copy and assignment operator to disallow peer copying
@ -36,11 +36,12 @@ public:
NetworkPeer& operator=(const NetworkPeer& otherPeer);
bool isNull() const { return _uuid.isNull(); }
bool hasSockets() const { return !_localSocket.isNull() && !_publicSocket.isNull(); }
const QUuid& getUUID() const { return _uuid; }
void setUUID(const QUuid& uuid) { _uuid = uuid; }
void reset();
void softReset();
const HifiSockAddr& getPublicSocket() const { return _publicSocket; }
virtual void setPublicSocket(const HifiSockAddr& publicSocket) { _publicSocket = publicSocket; }
@ -65,11 +66,11 @@ public:
float getOutboundBandwidth(); // in kbps
float getInboundBandwidth(); // in kbps
void startPingTimer();
void stopPingTimer();
friend QDataStream& operator<<(QDataStream& out, const NetworkPeer& peer);
friend QDataStream& operator>>(QDataStream& in, NetworkPeer& peer);
public slots:
void startPingTimer();
void stopPingTimer();
signals:
void pingTimerTimeout();
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
connect(&_domainHandler, &DomainHandler::iceSocketAndIDReceived, this, &NodeList::handleICEConnectionToDomainServer);
// handle ICE signal from DS so connection is attempted immediately
connect(&_domainHandler, &DomainHandler::requestICEConnectionAttempt, this, &NodeList::handleICEConnectionToDomainServer);
// handle ping timeout from DomainHandler to establish a connection with auto networked domain-server
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
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
qCDebug(networking) << "Waiting for inital public socket from STUN. Will not send domain-server check in.";
} else if (_domainHandler.getIP().isNull() && _domainHandler.requiresICE()) {
qCDebug(networking) << "Waiting for ICE discovered domain-server socket. Will not send domain-server check in.";
handleICEConnectionToDomainServer();
} else if (!_domainHandler.getIP().isNull()) {
bool isUsingDTLS = false;
@ -472,8 +476,9 @@ void NodeList::handleDSPathQueryResponse(const QByteArray& packet) {
}
void NodeList::handleICEConnectionToDomainServer() {
if (_domainHandler.getICEPeer().isNull()
|| _domainHandler.getICEPeer().getConnectionAttempts() >= MAX_ICE_CONNECTION_ATTEMPTS) {
// if we're still waiting to get sockets we want to ping for the domain-server
// then send another heartbeat now
if (!_domainHandler.getICEPeer().hasSockets()) {
_domainHandler.getICEPeer().resetConnectionAttempts();
@ -482,7 +487,24 @@ void NodeList::handleICEConnectionToDomainServer() {
LimitedNodeList::sendHeartbeatToIceServer(_domainHandler.getICEServerSockAddr(),
_domainHandler.getICEClientID(),
_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"
<< uuidStringWithoutCurlyBraces(_domainHandler.getICEDomainID());
@ -624,7 +646,7 @@ void NodeList::startNodeHolePunch(const SharedNodePointer& node) {
void NodeList::handleNodePingTimeout() {
SharedNodePointer senderNode = nodeWithUUID(qobject_cast<Node*>(sender())->getUUID());
if (senderNode) {
if (senderNode && !senderNode->getActiveSocket()) {
pingPunchForInactiveNode(senderNode);
}
}

View file

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