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:
Ray Greenwell
2006-03-30 01:08:32 +00:00
parent 07bc269f59
commit 981deb3b6b
2 changed files with 43 additions and 15 deletions
@@ -483,7 +483,7 @@ public class Client
if (_dcalc.isDone()) {
Log.debug("Time offset from server: " + _serverDelta + "ms.");
_dcalc = null;
} else {
} else if (_dcalc.shouldSendPing()) {
// otherwise, send another ping
PingRequest req = new PingRequest();
_comm.postMessage(req);
@@ -621,17 +621,15 @@ public class Client
*/
void gotPong (PongResponse pong)
{
// if we're not calculating our client/server time delta, then we
// don't need to do anything with the pong
if (_dcalc == null) {
return;
// if we're not currently calculating our client/server delta, then
// we can throw away the pong
if (_dcalc != null) {
// 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
// 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];
}
/**
* Should we send another ping?
*/
public boolean shouldSendPing ()
{
return (_ping == null) && !isDone();
}
/**
* 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
// response was received (both in client time)
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)
// and the processing delay incurred on the server
@@ -93,9 +102,30 @@ public class DeltaCalculator
*/
public long getTimeDelta ()
{
// sort the estimates and return one from the middle
Arrays.sort(_deltas);
return _deltas[_deltas.length/2];
if (_iter == 0) { // no responses yet
return 0L;
}
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];
}
}
/**