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()) {
|
||||
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];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user