From 8cd5ec3b54e4e5b0f1cdebf2bf20833e8ebcac2b Mon Sep 17 00:00:00 2001 From: wangyix Date: Fri, 6 Jun 2014 11:50:34 -0700 Subject: [PATCH] started work on sending nack packets from client --- .../src/octree/OctreeSendThread.cpp | 4 +- interface/src/Application.cpp | 59 ++++++++++++++++++- interface/src/Application.h | 6 ++ libraries/octree/src/OctreeSceneStats.cpp | 15 +++++ libraries/octree/src/OctreeSceneStats.h | 4 ++ 5 files changed, 85 insertions(+), 3 deletions(-) diff --git a/assignment-client/src/octree/OctreeSendThread.cpp b/assignment-client/src/octree/OctreeSendThread.cpp index befea80380..032b45fcdf 100644 --- a/assignment-client/src/octree/OctreeSendThread.cpp +++ b/assignment-client/src/octree/OctreeSendThread.cpp @@ -288,12 +288,12 @@ int OctreeSendThread::handlePacketSend(OctreeQueryNode* nodeData, int& trueBytes int OctreeSendThread::resendNackedPackets(OctreeQueryNode* nodeData) { - const int maxPacketsSent = 10; + const int MAX_PACKETS_RESEND = 10; int packetsSent = 0; const QByteArray* packet; - while (nodeData->hasNextNackedPacket() && packetsSent < maxPacketsSent) { + while (nodeData->hasNextNackedPacket() && packetsSent < MAX_PACKETS_RESEND) { packet = nodeData->getNextNackedPacket(); // packet will be NULL if it's not in nodeData's packet history if (packet) { diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index de3c354b27..358bb1bde3 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -167,7 +167,8 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : _applicationOverlay(), _runningScriptsWidget(new RunningScriptsWidget(_window)), _runningScriptsWidgetWasVisible(false), - _trayIcon(new QSystemTrayIcon(_window)) + _trayIcon(new QSystemTrayIcon(_window)), + _lastNackTime(usecTimestampNow()) { // read the ApplicationInfo.ini file for Name/Version/Domain information QSettings applicationInfo(Application::resourcesPath() + "info/ApplicationInfo.ini", QSettings::IniFormat); @@ -2091,7 +2092,63 @@ void Application::updateMyAvatar(float deltaTime) { _lastQueriedViewFrustum = _viewFrustum; } } + +// sent a nack packet containing missing sequence numbers of received packets +{ + quint64 now = usecTimestampNow(); + quint64 sinceLastNack = now - _lastNackTime; + const quint64 TOO_LONG_SINCE_LAST_NACK = 100 * MSECS_PER_SECOND; + if (sinceLastNack > TOO_LONG_SINCE_LAST_NACK) { + _lastNackTime = now; + + //_octreeServerSceneStats- + } } +} + + +void Application::sendNack() { + /* + // now that we know the node ID, let's add these stats to the stats for that node... + _octreeSceneStatsLock.lockForWrite(); + if (_octreeServerSceneStats.find(nodeUUID) != _octreeServerSceneStats.end()) { + OctreeSceneStats& stats = _octreeServerSceneStats[nodeUUID]; + stats.trackIncomingOctreePacket(packet, wasStatsPacket, sendingNode->getClockSkewUsec()); + } + _octreeSceneStatsLock.unlock(); + */ + + char packet[MAX_PACKET_SIZE]; + NodeList* nodeList = NodeList::getInstance(); + + // iterates thru all nodes in NodeList + foreach(const SharedNodePointer& node, NodeList::getInstance()->getNodeHash()) { + + char* dataAt = packet; + int bytesRemaining = MAX_PACKET_SIZE; + + int numBytesPacketHeader = populatePacketHeader(packet, PacketTypeOctreeDataNack, node->getUUID()); + dataAt += numBytesPacketHeader; + bytesRemaining -= numBytesPacketHeader; + + + + uint16_t numSequenceNumbers; + + + + + OctreeSceneStats& stats = _octreeServerSceneStats[node->getUUID()]; + int numSequenceNumbersAvailable = stats.getNumSequenceNumberToNack(); + + + // make sure we still have an active socket + nodeList->writeUnverifiedDatagram(reinterpret_cast(queryPacket), packetLength, node); + } +} + + + void Application::queryOctree(NodeType_t serverType, PacketType packetType, NodeToJurisdictionMap& jurisdictions) { diff --git a/interface/src/Application.h b/interface/src/Application.h index f3d9c0fd27..670ec35238 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -411,6 +411,10 @@ private: static void attachNewHeadToNode(Node *newNode); static void* networkReceive(void* args); // network receive thread + void sendNack(); + + + MainWindow* _window; GLCanvas* _glWidget; // our GLCanvas has a couple extra features @@ -580,6 +584,8 @@ private: bool _runningScriptsWidgetWasVisible; QSystemTrayIcon* _trayIcon; + +quint64 _lastNackTime; }; #endif // hifi_Application_h diff --git a/libraries/octree/src/OctreeSceneStats.cpp b/libraries/octree/src/OctreeSceneStats.cpp index 9580ae6d13..a25b72bedd 100644 --- a/libraries/octree/src/OctreeSceneStats.cpp +++ b/libraries/octree/src/OctreeSceneStats.cpp @@ -46,6 +46,7 @@ OctreeSceneStats::OctreeSceneStats() : _incomingReallyLate(0), _incomingPossibleDuplicate(0), _missingSequenceNumbers(), +_sequenceNumbersToNack(), _incomingFlightTimeAverage(samples), _jurisdictionRoot(NULL) { @@ -158,6 +159,7 @@ void OctreeSceneStats::copyFromOther(const OctreeSceneStats& other) { _incomingPossibleDuplicate = other._incomingPossibleDuplicate; _missingSequenceNumbers = other._missingSequenceNumbers; +_missingSequenceNumbersToNack = other._missingSequenceNumbersToNack; } @@ -926,6 +928,7 @@ void OctreeSceneStats::trackIncomingOctreePacket(const QByteArray& packet, qDebug() << "found it in _missingSequenceNumbers"; } _missingSequenceNumbers.remove(sequence); +_sequenceNumbersToNack.remove(sequence); _incomingLikelyLost--; _incomingRecovered++; } else { @@ -955,6 +958,7 @@ void OctreeSceneStats::trackIncomingOctreePacket(const QByteArray& packet, _incomingLikelyLost += missing; for(unsigned int missingSequence = expected; missingSequence < sequence; missingSequence++) { _missingSequenceNumbers << missingSequence; +_sequenceNumbersToNack << missingSequence; } } } @@ -982,9 +986,20 @@ void OctreeSceneStats::trackIncomingOctreePacket(const QByteArray& packet, qDebug() << "pruning really old missing sequence:" << missingItem; } _missingSequenceNumbers.remove(missingItem); +_sequenceNumbersToNack.remove(missingItem); } } } } +bool OctreeSceneStats::getNumSequenceNumberToNack() const { + return _sequenceNumbersToNack.size(); +} + +uint16_t OctreeSceneStats::getNextSequenceNumberToNack() { + QSet::Iterator it = _sequenceNumbersToNack.begin(); + uint16_t sequenceNumber = *it; + _sequenceNumbersToNack.remove(sequenceNumber); + return sequenceNumber; +} \ No newline at end of file diff --git a/libraries/octree/src/OctreeSceneStats.h b/libraries/octree/src/OctreeSceneStats.h index ef22fd7c1c..e6664083b0 100644 --- a/libraries/octree/src/OctreeSceneStats.h +++ b/libraries/octree/src/OctreeSceneStats.h @@ -172,6 +172,9 @@ public: quint32 getIncomingPossibleDuplicate() const { return _incomingPossibleDuplicate; } float getIncomingFlightTimeAverage() { return _incomingFlightTimeAverage.getAverage(); } +bool getNumSequenceNumberToNack() const; +uint16_t getNextSequenceNumberToNack(); + private: void copyFromOther(const OctreeSceneStats& other); @@ -273,6 +276,7 @@ private: quint32 _incomingReallyLate; /// out of order and later than MAX_MISSING_SEQUENCE_OLD_AGE late quint32 _incomingPossibleDuplicate; /// out of order possibly a duplicate QSet _missingSequenceNumbers; +QSet _sequenceNumbersToNack; SimpleMovingAverage _incomingFlightTimeAverage; // features related items