Skip to content

Commit

Permalink
Added a simple ping message to Qt netplay in an effort to measure rou…
Browse files Browse the repository at this point in the history
…nd trip message delay.
  • Loading branch information
thor2016 committed Feb 26, 2024
1 parent 015f6a0 commit 145fc16
Show file tree
Hide file tree
Showing 3 changed files with 150 additions and 1 deletion.
89 changes: 88 additions & 1 deletion src/drivers/Qt/NetPlay.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include "../../movie.h"
#include "../../debug.h"
#include "utils/crc32.h"
#include "utils/timeStamp.h"
#include "utils/StringUtils.h"
#include "Qt/main.h"
#include "Qt/dface.h"
Expand Down Expand Up @@ -482,6 +483,22 @@ void NetPlayServer::serverProcessMessage( NetPlayClient *client, void *msgBuf, s
}
}
break;
case NETPLAY_PING_RESP:
{

netPlayPingResp *ping = static_cast<netPlayPingResp*>(msgBuf);
ping->toHostByteOrder();

FCEU::timeStampRecord ts;
ts.readNew();

uint64_t diff = ts.toMilliSeconds() - ping->hostTimeStamp;

client->recordPingResult( diff );

//printf("Ping Latency ms: %llu Avg:%f\n", static_cast<unsigned long long>(diff), client->getAvgPingDelay());
}
break;
default:
printf("Unknown Msg: %08X\n", msgId);
break;
Expand All @@ -494,7 +511,7 @@ void NetPlayServer::update(void)
bool shouldRunFrame = false;
unsigned int clientMinFrame = 0xFFFFFFFF;
unsigned int clientMaxFrame = 0;
const uint32_t maxLead = 5u;
const uint32_t maxLead = maxLeadFrames;
const uint32_t currFrame = static_cast<uint32_t>(currFrameCounter);
const uint32_t leadFrame = currFrame + maxLead;
const uint32_t lastFrame = inputFrameBack();
Expand Down Expand Up @@ -606,7 +623,40 @@ void NetPlayServer::update(void)
}
}
}

bool shouldRunPing = (cycleCounter % 120) == 0;

if (shouldRunPing)
{
FCEU::timeStampRecord ts;
ts.readNew();

netPlayPingReq ping;
ping.hostTimeStamp = ts.toMilliSeconds();
ping.toNetworkByteOrder();

for (auto it = clientList.begin(); it != clientList.end(); it++)
{
NetPlayClient *client = *it;

if (client->state > 0)
{
sendMsg( client, &ping, sizeof(ping) );
}
}
}

bool shouldFlushOutput = true;
if (shouldFlushOutput)
{
for (auto it = clientList.begin(); it != clientList.end(); it++)
{
NetPlayClient *client = *it;

client->flushData();
}
}
cycleCounter++;
}
//-----------------------------------------------------------------------------
//--- NetPlayClient
Expand Down Expand Up @@ -784,6 +834,30 @@ void NetPlayClient::onSocketError(QAbstractSocket::SocketError error)
emit errorOccurred(errorMsg);
}
//-----------------------------------------------------------------------------
void NetPlayClient::recordPingResult( uint64_t delay_ms )
{
pingNumSamples++;
pingDelayLast = delay_ms;
pingDelaySum += delay_ms;
}
//-----------------------------------------------------------------------------
void NetPlayClient::resetPingData()
{
pingNumSamples = 0;
pingDelayLast = 0;
pingDelaySum = 0;
}
//-----------------------------------------------------------------------------
double NetPlayClient::getAvgPingDelay()
{
double ms = 0.0;
if (pingNumSamples > 0)
{
ms = static_cast<double>(pingDelaySum) / static_cast<double>(pingNumSamples);
}
return ms;
}
//-----------------------------------------------------------------------------
static void clientMessageCallback( void *userData, void *msgBuf, size_t msgSize )
{
NetPlayClient *client = static_cast<NetPlayClient*>(userData);
Expand Down Expand Up @@ -821,6 +895,8 @@ void NetPlayClient::update(void)

statusMsg.toNetworkByteOrder();
sock->write( reinterpret_cast<const char*>(&statusMsg), sizeof(statusMsg) );

flushData();
}
}
//-----------------------------------------------------------------------------
Expand Down Expand Up @@ -995,6 +1071,17 @@ void NetPlayClient::clientProcessMessage( void *msgBuf, size_t msgSize )
}
}
break;
case NETPLAY_PING_REQ:
{
netPlayPingResp pong;
netPlayPingReq *ping = static_cast<netPlayPingReq*>(msgBuf);
ping->toHostByteOrder();

pong.hostTimeStamp = ping->hostTimeStamp;
pong.toNetworkByteOrder();
sock->write( (const char*)&pong, sizeof(netPlayPingResp) );
}
break;
default:
printf("Unknown Msg: %08X\n", msgId);
break;
Expand Down
12 changes: 12 additions & 0 deletions src/drivers/Qt/NetPlay.h
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,9 @@ class NetPlayServer : public QTcpServer
void setRole(int _role);
bool claimRole(NetPlayClient* client, int _role);

uint32_t getMaxLeadFrames(){ return maxLeadFrames; }
void setMaxLeadFrames(uint32_t value){ maxLeadFrames = value; }

void serverProcessMessage( NetPlayClient *client, void *msgBuf, size_t msgSize );

QString sessionName;
Expand All @@ -135,6 +138,8 @@ class NetPlayServer : public QTcpServer
int roleMask = 0;
NetPlayClient* clientPlayer[4] = { nullptr };
int forceResyncCount = 10;
uint32_t cycleCounter = 0;
uint32_t maxLeadFrames = 10u;

public slots:
void newConnectionRdy(void);
Expand Down Expand Up @@ -209,6 +214,9 @@ class NetPlayClient : public QObject
bool shouldDestroy(){ return needsDestroy; }
bool isPaused(){ return paused; }
void setPaused(bool value){ paused = value; }
void recordPingResult( uint64_t delay_ms );
void resetPingData(void);
double getAvgPingDelay();

QString userName;
QString password;
Expand All @@ -234,6 +242,10 @@ class NetPlayClient : public QObject
bool _connected = false;
bool paused = false;

uint64_t pingDelaySum = 0;
uint64_t pingDelayLast = 0;
uint64_t pingNumSamples = 0;

std::list <NetPlayFrameInput> input;
FCEU::mutex inputMtx;

Expand Down
50 changes: 50 additions & 0 deletions src/drivers/Qt/NetPlayMsgDef.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ enum netPlayMsgType
NETPLAY_RUN_FRAME_REQ,
NETPLAY_CLIENT_STATE,
NETPLAY_ERROR_MSG,
NETPLAY_PING_REQ,
NETPLAY_PING_RESP,
};

enum netPlayerId
Expand Down Expand Up @@ -269,5 +271,53 @@ struct netPlayClientState
}
};

struct netPlayPingReq
{
netPlayMsgHdr hdr;

uint64_t hostTimeStamp;

netPlayPingReq(void)
: hdr(NETPLAY_PING_REQ, sizeof(netPlayPingReq)), hostTimeStamp(0)
{
}

void toHostByteOrder()
{
hdr.toHostByteOrder();
hostTimeStamp = netPlayByteSwap(hostTimeStamp);
}

void toNetworkByteOrder()
{
hdr.toNetworkByteOrder();
hostTimeStamp = netPlayByteSwap(hostTimeStamp);
}
};

struct netPlayPingResp
{
netPlayMsgHdr hdr;

uint64_t hostTimeStamp;

netPlayPingResp(void)
: hdr(NETPLAY_PING_RESP, sizeof(netPlayPingResp)), hostTimeStamp(0)
{
}

void toHostByteOrder()
{
hdr.toHostByteOrder();
hostTimeStamp = netPlayByteSwap(hostTimeStamp);
}

void toNetworkByteOrder()
{
hdr.toNetworkByteOrder();
hostTimeStamp = netPlayByteSwap(hostTimeStamp);
}
};


#pragma pack(pop)

0 comments on commit 145fc16

Please sign in to comment.