Modified clock synchronization approach slightly so that we allow 5

seconds to pass in between ping/pong latency samples. Additionally, we
resync the clock every 10 minutes.


git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@2748 542714f4-19e9-0310-aa3c-eee0fc999fb1
This commit is contained in:
Michael Bayne
2003-08-08 20:20:39 +00:00
parent 3034364579
commit 732c0aab41
2 changed files with 81 additions and 71 deletions
@@ -1,5 +1,5 @@
//
// $Id: Client.java,v 1.39 2003/07/17 21:39:15 mdb Exp $
// $Id: Client.java,v 1.40 2003/08/08 20:20:39 mdb Exp $
package com.threerings.presents.client;
@@ -8,6 +8,8 @@ import java.util.List;
import com.samskivert.util.ObserverList;
import com.samskivert.util.ResultListener;
import com.samskivert.util.Interval;
import com.samskivert.util.IntervalManager;
import com.threerings.presents.Log;
import com.threerings.presents.data.ClientObject;
@@ -322,6 +324,18 @@ public class Client
// this will initiate the logon process
_comm = new Communicator(this);
_comm.logon();
// register an interval that we'll use to keep the clock synced
// and to send pings when appropriate
_piid = IntervalManager.register(new Interval() {
public void intervalExpired (int id, Object arg) {
if (id != _piid) {
IntervalManager.remove(id);
} else {
tick();
}
}
}, 5000L, null, true);
}
/**
@@ -351,6 +365,9 @@ public class Client
return false;
}
// kill our tick interval
_piid = -1;
// ask the communicator to send a logoff message and disconnect
// from the server
_comm.logoff();
@@ -358,34 +375,46 @@ public class Client
return true;
}
/**
* Called every five seconds; ensures that we ping the server if we
* haven't communicated in a long while and periodically resyncs the
* client and server clock deltas.
*/
protected void tick ()
{
long now = System.currentTimeMillis();
if (_dcalc != null) {
// if we're syncing the clock, send another ping
PingRequest req = new PingRequest();
_comm.postMessage(req);
_dcalc.sentPing(req);
} else if (now - _comm.getLastWrite() > PingRequest.PING_INTERVAL) {
// if we haven't sent anything over the network in a while, we
// ping the server to let it know that we're still alive
_comm.postMessage(new PingRequest());
} else if (now - _lastSync > CLOCK_SYNC_INTERVAL) {
// resync our clock with the server
establishClockDelta(now);
}
}
/**
* Called during initialization to initiate a sequence of ping/pong
* messages which will be used to determine (with "good enough"
* accuracy) the difference between the client clock and the server
* clock so that we can later interpret server timestamps.
*/
protected void establishClockDelta ()
protected void establishClockDelta (long now)
{
// create a new delta calculator and start the process
_dcalc = new DeltaCalculator();
PingRequest req = new PingRequest();
_comm.postMessage(req);
_dcalc.sentPing(req);
}
/**
* This is called when we've completed the process of pinging the
* server a few times to establish our clock delta.
*/
protected void clockDeltaEstablished ()
{
// initialize our invocation director
_invdir.init(_comm.getDObjectManager(), _cloid, this);
// we can't quite call initialization completed at this point
// because we need for the invocation director to fully initialize
// (which requires a round trip to the server) before turning the
// client loose to do things like request invocation services
_lastSync = now;
}
/**
@@ -484,9 +513,17 @@ public class Client
// extract bootstrap information
_cloid = data.clientOid;
// initialize our invocation director
_invdir.init(_comm.getDObjectManager(), _cloid, this);
// send a few pings to the server to establish the clock offset
// between this client and server standard time
establishClockDelta();
establishClockDelta(System.currentTimeMillis());
// we can't quite call initialization completed at this point
// because we need for the invocation director to fully initialize
// (which requires a round trip to the server) before turning the
// client loose to do things like request invocation services
}
/**
@@ -502,21 +539,15 @@ public class Client
return;
}
if (_dcalc.gotPong(pong)) {
// we're either done with our calculations, so we can grab the
// time delta and finish our business...
_serverDelta = _dcalc.getTimeDelta();
// free up our delta calculator
_dcalc = null;
// let the client continue with its initialization
clockDeltaEstablished();
Log.info("Time offset from server: " + _serverDelta + "ms.");
// 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
boolean done = _dcalc.gotPong(pong);
_serverDelta = _dcalc.getTimeDelta();
} else {
// ...or we'll either be sending another ping
PingRequest req = new PingRequest();
_comm.postMessage(req);
_dcalc.sentPing(req);
if (done) {
Log.info("Time offset from server: " + _serverDelta + "ms.");
_dcalc = null;
}
}
@@ -637,6 +668,15 @@ public class Client
* server. */
protected DeltaCalculator _dcalc;
/** The last time at which we synced our clock with the server. */
protected long _lastSync;
/** Our tick interval id. */
protected int _piid = -1;
/** How often we recompute our time offset from the server. */
protected static final long CLOCK_SYNC_INTERVAL = 600 * 1000L;
// client observer codes
static final int CLIENT_DID_LOGON = 0;
static final int CLIENT_FAILED_TO_LOGON = 1;