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 "../../movie.h"
|
||||||
#include "../../debug.h"
|
#include "../../debug.h"
|
||||||
#include "utils/crc32.h"
|
#include "utils/crc32.h"
|
||||||
|
#include "utils/timeStamp.h"
|
||||||
#include "utils/StringUtils.h"
|
#include "utils/StringUtils.h"
|
||||||
#include "Qt/main.h"
|
#include "Qt/main.h"
|
||||||
#include "Qt/dface.h"
|
#include "Qt/dface.h"
|
||||||
|
@ -482,6 +483,22 @@ void NetPlayServer::serverProcessMessage( NetPlayClient *client, void *msgBuf, s
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
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:
|
default:
|
||||||
printf("Unknown Msg: %08X\n", msgId);
|
printf("Unknown Msg: %08X\n", msgId);
|
||||||
break;
|
break;
|
||||||
|
@ -494,7 +511,7 @@ void NetPlayServer::update(void)
|
||||||
bool shouldRunFrame = false;
|
bool shouldRunFrame = false;
|
||||||
unsigned int clientMinFrame = 0xFFFFFFFF;
|
unsigned int clientMinFrame = 0xFFFFFFFF;
|
||||||
unsigned int clientMaxFrame = 0;
|
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 currFrame = static_cast<uint32_t>(currFrameCounter);
|
||||||
const uint32_t leadFrame = currFrame + maxLead;
|
const uint32_t leadFrame = currFrame + maxLead;
|
||||||
const uint32_t lastFrame = inputFrameBack();
|
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
|
//--- NetPlayClient
|
||||||
|
@ -784,6 +834,30 @@ void NetPlayClient::onSocketError(QAbstractSocket::SocketError error)
|
||||||
emit errorOccurred(errorMsg);
|
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 )
|
static void clientMessageCallback( void *userData, void *msgBuf, size_t msgSize )
|
||||||
{
|
{
|
||||||
NetPlayClient *client = static_cast<NetPlayClient*>(userData);
|
NetPlayClient *client = static_cast<NetPlayClient*>(userData);
|
||||||
|
@ -821,6 +895,8 @@ void NetPlayClient::update(void)
|
||||||
|
|
||||||
statusMsg.toNetworkByteOrder();
|
statusMsg.toNetworkByteOrder();
|
||||||
sock->write( reinterpret_cast<const char*>(&statusMsg), sizeof(statusMsg) );
|
sock->write( reinterpret_cast<const char*>(&statusMsg), sizeof(statusMsg) );
|
||||||
|
|
||||||
|
flushData();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
@ -995,6 +1071,17 @@ void NetPlayClient::clientProcessMessage( void *msgBuf, size_t msgSize )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
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:
|
default:
|
||||||
printf("Unknown Msg: %08X\n", msgId);
|
printf("Unknown Msg: %08X\n", msgId);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -119,6 +119,9 @@ class NetPlayServer : public QTcpServer
|
||||||
void setRole(int _role);
|
void setRole(int _role);
|
||||||
bool claimRole(NetPlayClient* client, 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 );
|
void serverProcessMessage( NetPlayClient *client, void *msgBuf, size_t msgSize );
|
||||||
|
|
||||||
QString sessionName;
|
QString sessionName;
|
||||||
|
@ -135,6 +138,8 @@ class NetPlayServer : public QTcpServer
|
||||||
int roleMask = 0;
|
int roleMask = 0;
|
||||||
NetPlayClient* clientPlayer[4] = { nullptr };
|
NetPlayClient* clientPlayer[4] = { nullptr };
|
||||||
int forceResyncCount = 10;
|
int forceResyncCount = 10;
|
||||||
|
uint32_t cycleCounter = 0;
|
||||||
|
uint32_t maxLeadFrames = 10u;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void newConnectionRdy(void);
|
void newConnectionRdy(void);
|
||||||
|
@ -209,6 +214,9 @@ class NetPlayClient : public QObject
|
||||||
bool shouldDestroy(){ return needsDestroy; }
|
bool shouldDestroy(){ return needsDestroy; }
|
||||||
bool isPaused(){ return paused; }
|
bool isPaused(){ return paused; }
|
||||||
void setPaused(bool value){ paused = value; }
|
void setPaused(bool value){ paused = value; }
|
||||||
|
void recordPingResult( uint64_t delay_ms );
|
||||||
|
void resetPingData(void);
|
||||||
|
double getAvgPingDelay();
|
||||||
|
|
||||||
QString userName;
|
QString userName;
|
||||||
QString password;
|
QString password;
|
||||||
|
@ -234,6 +242,10 @@ class NetPlayClient : public QObject
|
||||||
bool _connected = false;
|
bool _connected = false;
|
||||||
bool paused = false;
|
bool paused = false;
|
||||||
|
|
||||||
|
uint64_t pingDelaySum = 0;
|
||||||
|
uint64_t pingDelayLast = 0;
|
||||||
|
uint64_t pingNumSamples = 0;
|
||||||
|
|
||||||
std::list <NetPlayFrameInput> input;
|
std::list <NetPlayFrameInput> input;
|
||||||
FCEU::mutex inputMtx;
|
FCEU::mutex inputMtx;
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,8 @@ enum netPlayMsgType
|
||||||
NETPLAY_RUN_FRAME_REQ,
|
NETPLAY_RUN_FRAME_REQ,
|
||||||
NETPLAY_CLIENT_STATE,
|
NETPLAY_CLIENT_STATE,
|
||||||
NETPLAY_ERROR_MSG,
|
NETPLAY_ERROR_MSG,
|
||||||
|
NETPLAY_PING_REQ,
|
||||||
|
NETPLAY_PING_RESP,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum netPlayerId
|
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)
|
#pragma pack(pop)
|
||||||
|
|
Loading…
Reference in New Issue