Added a simple ping message to Qt netplay in an effort to measure round trip message delay.
This commit is contained in:
parent
015f6a0acd
commit
145fc1614f
|
@ -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"
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -821,6 +895,8 @@ void NetPlayClient::update(void)
|
|||
|
||||
statusMsg.toNetworkByteOrder();
|
||||
sock->write( reinterpret_cast<const char*>(&statusMsg), sizeof(statusMsg) );
|
||||
|
||||
flushData();
|
||||
}
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
|
|
@ -22,6 +22,8 @@ enum netPlayMsgType
|
|||
NETPLAY_RUN_FRAME_REQ,
|
||||
NETPLAY_CLIENT_STATE,
|
||||
NETPLAY_ERROR_MSG,
|
||||
NETPLAY_PING_REQ,
|
||||
NETPLAY_PING_RESP,
|
||||
};
|
||||
|
||||
enum netPlayerId
|
||||
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue