Fixed two bugs with delta calculation:
- if a pong response took more than 5 seconds to receive, another ping would be sent. When the pong finally arrived the delta would be calculated using the most recently sent ping. Fix: don't send more pings while waiting on a pong. - After a pong is received, the _deltas array is mangled while calculating the server delta, making subsequent pongs possibly overwrite earlier calculated deltas. Fix: calculate using a copy. Also, changed the delta calculation to be the mean of the deltas rather than the median. Left code in to do it both ways if this change was not kosher... git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@3990 542714f4-19e9-0310-aa3c-eee0fc999fb1
This commit is contained in:
@@ -483,7 +483,7 @@ public class Client
|
|||||||
if (_dcalc.isDone()) {
|
if (_dcalc.isDone()) {
|
||||||
Log.debug("Time offset from server: " + _serverDelta + "ms.");
|
Log.debug("Time offset from server: " + _serverDelta + "ms.");
|
||||||
_dcalc = null;
|
_dcalc = null;
|
||||||
} else {
|
} else if (_dcalc.shouldSendPing()) {
|
||||||
// otherwise, send another ping
|
// otherwise, send another ping
|
||||||
PingRequest req = new PingRequest();
|
PingRequest req = new PingRequest();
|
||||||
_comm.postMessage(req);
|
_comm.postMessage(req);
|
||||||
@@ -621,17 +621,15 @@ public class Client
|
|||||||
*/
|
*/
|
||||||
void gotPong (PongResponse pong)
|
void gotPong (PongResponse pong)
|
||||||
{
|
{
|
||||||
// if we're not calculating our client/server time delta, then we
|
// if we're not currently calculating our client/server delta, then
|
||||||
// don't need to do anything with the pong
|
// we can throw away the pong
|
||||||
if (_dcalc == null) {
|
if (_dcalc != null) {
|
||||||
return;
|
// we update the delta after every receipt so as to immediately
|
||||||
|
// obtain an estimate of the clock delta and then refine it as
|
||||||
|
// more packets come in
|
||||||
|
_dcalc.gotPong(pong);
|
||||||
|
_serverDelta = _dcalc.getTimeDelta();
|
||||||
}
|
}
|
||||||
|
|
||||||
// we update the delta after every receipt so as to immediately
|
|
||||||
// obtain an estimate of the clock delta and then refine it as
|
|
||||||
// more packets come in
|
|
||||||
_dcalc.gotPong(pong);
|
|
||||||
_serverDelta = _dcalc.getTimeDelta();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// $Id: DeltaCalculator.java,v 1.8 2004/10/22 01:19:55 mdb Exp $
|
// $Id$
|
||||||
//
|
//
|
||||||
// Narya library - tools for developing networked games
|
// Narya library - tools for developing networked games
|
||||||
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
|
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
|
||||||
@@ -45,6 +45,14 @@ public class DeltaCalculator
|
|||||||
_deltas = new long[CLOCK_SYNC_PING_COUNT];
|
_deltas = new long[CLOCK_SYNC_PING_COUNT];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Should we send another ping?
|
||||||
|
*/
|
||||||
|
public boolean shouldSendPing ()
|
||||||
|
{
|
||||||
|
return (_ping == null) && !isDone();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Must be called when a ping message is sent to the server.
|
* Must be called when a ping message is sent to the server.
|
||||||
*/
|
*/
|
||||||
@@ -69,6 +77,7 @@ public class DeltaCalculator
|
|||||||
// make a note of when the ping message was sent and when the pong
|
// make a note of when the ping message was sent and when the pong
|
||||||
// response was received (both in client time)
|
// response was received (both in client time)
|
||||||
long send = _ping.getPackStamp(), recv = pong.getUnpackStamp();
|
long send = _ping.getPackStamp(), recv = pong.getUnpackStamp();
|
||||||
|
_ping = null; // clear out the saved sent ping
|
||||||
|
|
||||||
// make a note of when the pong response was sent (in server time)
|
// make a note of when the pong response was sent (in server time)
|
||||||
// and the processing delay incurred on the server
|
// and the processing delay incurred on the server
|
||||||
@@ -93,9 +102,30 @@ public class DeltaCalculator
|
|||||||
*/
|
*/
|
||||||
public long getTimeDelta ()
|
public long getTimeDelta ()
|
||||||
{
|
{
|
||||||
// sort the estimates and return one from the middle
|
if (_iter == 0) { // no responses yet
|
||||||
Arrays.sort(_deltas);
|
return 0L;
|
||||||
return _deltas[_deltas.length/2];
|
}
|
||||||
|
|
||||||
|
if (true) {
|
||||||
|
// return the mean
|
||||||
|
long est = 0;
|
||||||
|
for (int ii=0; ii < _iter; ii++) {
|
||||||
|
est += _deltas[ii];
|
||||||
|
}
|
||||||
|
return (est / _iter);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// return the median value
|
||||||
|
|
||||||
|
// copy the deltas array so that we don't alter things before
|
||||||
|
// all pongs have arrived
|
||||||
|
long[] deltasCopy = new long[_iter];
|
||||||
|
System.arraycopy(_deltas, 0, deltasCopy, 0, _iter);
|
||||||
|
|
||||||
|
// sort the estimates and return one from the middle
|
||||||
|
Arrays.sort(deltasCopy);
|
||||||
|
return deltasCopy[deltasCopy.length/2];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user