diff --git a/audio-mixer/src/main.cpp b/audio-mixer/src/main.cpp index 5f9b79264c..d473a8172e 100644 --- a/audio-mixer/src/main.cpp +++ b/audio-mixer/src/main.cpp @@ -391,6 +391,10 @@ int main(int argc, const char* argv[]) { // give the new audio data to the matching injector agent agentList->updateAgentWithData(matchingInjector, packetData, receivedBytes); + } else if (packetData[0] == PACKET_HEADER_PING) { + + // If the packet is a ping, let processAgentData handle it. + agentList->processAgentData(agentAddress, packetData, receivedBytes); } } diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 776fbfc9bb..7177ea1813 100755 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -833,9 +833,23 @@ void Application::wheelEvent(QWheelEvent* event) { } } +void sendPingPackets() { + + char agentTypesOfInterest[] = {AGENT_TYPE_VOXEL_SERVER, AGENT_TYPE_AUDIO_MIXER, AGENT_TYPE_AVATAR_MIXER}; + long long currentTime = usecTimestampNow(); + char pingPacket[1 + sizeof(currentTime)]; + pingPacket[0] = PACKET_HEADER_PING; + + memcpy(&pingPacket[1], ¤tTime, sizeof(currentTime)); + AgentList::getInstance()->broadcastToAgents((unsigned char*)pingPacket, 1 + sizeof(currentTime), agentTypesOfInterest, 3); + +} + // Every second, check the frame rates and other stuff void Application::timer() { gettimeofday(&_timerEnd, NULL); + sendPingPackets(); + _fps = (float)_frameCount / ((float)diffclock(&_timerStart, &_timerEnd) / 1000.f); _packetsPerSecond = (float)_packetCount / ((float)diffclock(&_timerStart, &_timerEnd) / 1000.f); _bytesPerSecond = (float)_bytesCount / ((float)diffclock(&_timerStart, &_timerEnd) / 1000.f); @@ -2279,6 +2293,24 @@ void Application::displayStats() { sprintf(stats, "%3.0f FPS, %d Pkts/sec, %3.2f Mbps", _fps, _packetsPerSecond, (float)_bytesPerSecond * 8.f / 1000000.f); drawtext(10, statsVerticalOffset + 15, 0.10f, 0, 1.0, 0, stats); + + int pingAudio = 0, pingAvatar = 0, pingVoxel = 0; + + AgentList *agentList = AgentList::getInstance(); + Agent *audioMixerAgent = agentList->soloAgentOfType(AGENT_TYPE_AUDIO_MIXER); + Agent *avatarMixerAgent = agentList->soloAgentOfType(AGENT_TYPE_AVATAR); + Agent *voxelServerAgent = agentList->soloAgentOfType(AGENT_TYPE_VOXEL_SERVER); + + if (audioMixerAgent != NULL) + pingAudio = audioMixerAgent->getPingMs(); + if (avatarMixerAgent != NULL) + pingAvatar = avatarMixerAgent->getPingMs(); + if (voxelServerAgent != NULL) + pingVoxel = voxelServerAgent->getPingMs(); + + char pingStats[200]; + sprintf(pingStats, "Ping audio/avatar/voxel: %d / %d / %d ", pingAudio, pingAvatar, pingVoxel); + drawtext(10, statsVerticalOffset + 35, 0.10f, 0, 1.0, 0, pingStats); std::stringstream voxelStats; voxelStats.precision(4); diff --git a/interface/src/Application.h b/interface/src/Application.h index 8667e68356..baf4fceea0 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -335,6 +335,7 @@ private: int _packetsPerSecond; int _bytesPerSecond; int _bytesCount; + }; #endif /* defined(__interface__Application__) */ diff --git a/libraries/shared/src/Agent.h b/libraries/shared/src/Agent.h index 18d42fdf3d..bafffb008e 100644 --- a/libraries/shared/src/Agent.h +++ b/libraries/shared/src/Agent.h @@ -63,6 +63,9 @@ public: float getAverageKilobitsPerSecond(); float getAveragePacketsPerSecond(); + int getPingMs() const { return _pingMs; }; + void setPingMs(int pingMs) { _pingMs = pingMs; }; + static void printLog(Agent const&); private: // privatize copy and assignment operator to disallow Agent copying @@ -79,6 +82,7 @@ private: SimpleMovingAverage* _bytesReceivedMovingAverage; AgentData* _linkedData; bool _isAlive; + int _pingMs; }; diff --git a/libraries/shared/src/AgentList.cpp b/libraries/shared/src/AgentList.cpp index 7a4803586e..237b367252 100644 --- a/libraries/shared/src/AgentList.cpp +++ b/libraries/shared/src/AgentList.cpp @@ -77,6 +77,17 @@ AgentList::~AgentList() { pthread_mutex_destroy(&mutex); } +void AgentList::timePingReply(sockaddr *agentAddress, unsigned char *packetData) { + for(AgentList::iterator agent = begin(); agent != end(); agent++) { + if (socketMatch(agent->getPublicSocket(), agentAddress) || + socketMatch(agent->getLocalSocket(), agentAddress)) { + int pingTime = usecTimestampNow() - *(long long *)(packetData + 1); + agent->setPingMs(pingTime / 1000); + break; + } + } +} + void AgentList::processAgentData(sockaddr *senderAddress, unsigned char *packetData, size_t dataBytes) { switch (((char *)packetData)[0]) { case PACKET_HEADER_DOMAIN: { @@ -84,11 +95,14 @@ void AgentList::processAgentData(sockaddr *senderAddress, unsigned char *packetD break; } case PACKET_HEADER_PING: { - _agentSocket.send(senderAddress, &PACKET_HEADER_PING_REPLY, 1); + char pingPacket[dataBytes]; + memcpy(pingPacket, packetData, dataBytes); + pingPacket[0] = PACKET_HEADER_PING_REPLY; + _agentSocket.send(senderAddress, pingPacket, dataBytes); break; } case PACKET_HEADER_PING_REPLY: { - handlePingReply(senderAddress); + timePingReply(senderAddress, packetData); break; } } diff --git a/libraries/shared/src/AgentList.h b/libraries/shared/src/AgentList.h index 1b51913928..8a283009fe 100644 --- a/libraries/shared/src/AgentList.h +++ b/libraries/shared/src/AgentList.h @@ -116,6 +116,7 @@ private: pthread_mutex_t mutex; void handlePingReply(sockaddr *agentAddress); + void timePingReply(sockaddr *agentAddress, unsigned char *packetData); }; class AgentListIterator : public std::iterator { diff --git a/voxel-server/src/main.cpp b/voxel-server/src/main.cpp index f8b8c2f36e..a73a8dd09a 100644 --- a/voxel-server/src/main.cpp +++ b/voxel-server/src/main.cpp @@ -706,6 +706,10 @@ int main(int argc, const char * argv[]) { agentList->updateAgentWithData(agent, packetData, receivedBytes); } + // If the packet is a ping, let processAgentData handle it. + if (packetData[0] == PACKET_HEADER_PING) { + agentList->processAgentData(&agentPublicAddress, packetData, receivedBytes); + } } }