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:
@@ -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;
|
package com.threerings.presents.client;
|
||||||
|
|
||||||
@@ -8,6 +8,8 @@ import java.util.List;
|
|||||||
|
|
||||||
import com.samskivert.util.ObserverList;
|
import com.samskivert.util.ObserverList;
|
||||||
import com.samskivert.util.ResultListener;
|
import com.samskivert.util.ResultListener;
|
||||||
|
import com.samskivert.util.Interval;
|
||||||
|
import com.samskivert.util.IntervalManager;
|
||||||
|
|
||||||
import com.threerings.presents.Log;
|
import com.threerings.presents.Log;
|
||||||
import com.threerings.presents.data.ClientObject;
|
import com.threerings.presents.data.ClientObject;
|
||||||
@@ -322,6 +324,18 @@ public class Client
|
|||||||
// this will initiate the logon process
|
// this will initiate the logon process
|
||||||
_comm = new Communicator(this);
|
_comm = new Communicator(this);
|
||||||
_comm.logon();
|
_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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// kill our tick interval
|
||||||
|
_piid = -1;
|
||||||
|
|
||||||
// ask the communicator to send a logoff message and disconnect
|
// ask the communicator to send a logoff message and disconnect
|
||||||
// from the server
|
// from the server
|
||||||
_comm.logoff();
|
_comm.logoff();
|
||||||
@@ -358,34 +375,46 @@ public class Client
|
|||||||
return true;
|
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
|
* Called during initialization to initiate a sequence of ping/pong
|
||||||
* messages which will be used to determine (with "good enough"
|
* messages which will be used to determine (with "good enough"
|
||||||
* accuracy) the difference between the client clock and the server
|
* accuracy) the difference between the client clock and the server
|
||||||
* clock so that we can later interpret server timestamps.
|
* 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
|
// create a new delta calculator and start the process
|
||||||
_dcalc = new DeltaCalculator();
|
_dcalc = new DeltaCalculator();
|
||||||
PingRequest req = new PingRequest();
|
PingRequest req = new PingRequest();
|
||||||
_comm.postMessage(req);
|
_comm.postMessage(req);
|
||||||
_dcalc.sentPing(req);
|
_dcalc.sentPing(req);
|
||||||
}
|
_lastSync = now;
|
||||||
|
|
||||||
/**
|
|
||||||
* 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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -484,9 +513,17 @@ public class Client
|
|||||||
// extract bootstrap information
|
// extract bootstrap information
|
||||||
_cloid = data.clientOid;
|
_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
|
// send a few pings to the server to establish the clock offset
|
||||||
// between this client and server standard time
|
// 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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_dcalc.gotPong(pong)) {
|
// we update the delta after every receipt so as to immediately
|
||||||
// we're either done with our calculations, so we can grab the
|
// obtain an estimate of the clock delta and then refine it as
|
||||||
// time delta and finish our business...
|
// more packets come in
|
||||||
_serverDelta = _dcalc.getTimeDelta();
|
boolean done = _dcalc.gotPong(pong);
|
||||||
// free up our delta calculator
|
_serverDelta = _dcalc.getTimeDelta();
|
||||||
_dcalc = null;
|
|
||||||
// let the client continue with its initialization
|
|
||||||
clockDeltaEstablished();
|
|
||||||
Log.info("Time offset from server: " + _serverDelta + "ms.");
|
|
||||||
|
|
||||||
} else {
|
if (done) {
|
||||||
// ...or we'll either be sending another ping
|
Log.info("Time offset from server: " + _serverDelta + "ms.");
|
||||||
PingRequest req = new PingRequest();
|
_dcalc = null;
|
||||||
_comm.postMessage(req);
|
|
||||||
_dcalc.sentPing(req);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -637,6 +668,15 @@ public class Client
|
|||||||
* server. */
|
* server. */
|
||||||
protected DeltaCalculator _dcalc;
|
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
|
// client observer codes
|
||||||
static final int CLIENT_DID_LOGON = 0;
|
static final int CLIENT_DID_LOGON = 0;
|
||||||
static final int CLIENT_FAILED_TO_LOGON = 1;
|
static final int CLIENT_FAILED_TO_LOGON = 1;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// $Id: Communicator.java,v 1.32 2003/07/17 21:39:15 mdb Exp $
|
// $Id: Communicator.java,v 1.33 2003/08/08 20:20:39 mdb Exp $
|
||||||
|
|
||||||
package com.threerings.presents.client;
|
package com.threerings.presents.client;
|
||||||
|
|
||||||
@@ -13,8 +13,6 @@ import java.net.InetAddress;
|
|||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
|
|
||||||
import com.samskivert.io.NestableIOException;
|
import com.samskivert.io.NestableIOException;
|
||||||
import com.samskivert.util.Interval;
|
|
||||||
import com.samskivert.util.IntervalManager;
|
|
||||||
import com.samskivert.util.LoopingThread;
|
import com.samskivert.util.LoopingThread;
|
||||||
import com.samskivert.util.Queue;
|
import com.samskivert.util.Queue;
|
||||||
import com.samskivert.util.RuntimeAdjust;
|
import com.samskivert.util.RuntimeAdjust;
|
||||||
@@ -96,15 +94,6 @@ public class Communicator
|
|||||||
// start up the writer thread if everything went successfully
|
// start up the writer thread if everything went successfully
|
||||||
_reader = new Reader();
|
_reader = new Reader();
|
||||||
_reader.start();
|
_reader.start();
|
||||||
|
|
||||||
// register an interval to send pings when appropriate
|
|
||||||
_piid = IntervalManager.register(new Interval() {
|
|
||||||
public void intervalExpired (int id, Object arg) {
|
|
||||||
if (checkNeedsPing()) {
|
|
||||||
postMessage(new PingRequest());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, 5000L, null, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -120,8 +109,6 @@ public class Communicator
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
stopPingInterval();
|
|
||||||
|
|
||||||
// post a logoff message
|
// post a logoff message
|
||||||
postMessage(new LogoffRequest());
|
postMessage(new LogoffRequest());
|
||||||
|
|
||||||
@@ -236,9 +223,6 @@ public class Communicator
|
|||||||
// clear out our reader reference
|
// clear out our reader reference
|
||||||
_reader = null;
|
_reader = null;
|
||||||
|
|
||||||
// in case we haven't already done it.
|
|
||||||
stopPingInterval();
|
|
||||||
|
|
||||||
if (_writer == null) {
|
if (_writer == null) {
|
||||||
// there's no writer during authentication, so we may be
|
// there's no writer during authentication, so we may be
|
||||||
// responsible for closing the socket channel
|
// responsible for closing the socket channel
|
||||||
@@ -331,6 +315,14 @@ public class Communicator
|
|||||||
updateWriteStamp();
|
updateWriteStamp();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the time at which we last sent a packet to the server.
|
||||||
|
*/
|
||||||
|
protected synchronized long getLastWrite ()
|
||||||
|
{
|
||||||
|
return _lastWrite;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Makes a note of the time at which we last communicated with the
|
* Makes a note of the time at which we last communicated with the
|
||||||
* server.
|
* server.
|
||||||
@@ -340,27 +332,6 @@ public class Communicator
|
|||||||
_lastWrite = System.currentTimeMillis();
|
_lastWrite = System.currentTimeMillis();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks to see if we need to send a ping to the server because we
|
|
||||||
* haven't communicated in sufficiently long.
|
|
||||||
*/
|
|
||||||
protected synchronized boolean checkNeedsPing ()
|
|
||||||
{
|
|
||||||
long now = System.currentTimeMillis();
|
|
||||||
return (now - _lastWrite > PingRequest.PING_INTERVAL);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Stops our ping interval.
|
|
||||||
*/
|
|
||||||
protected void stopPingInterval ()
|
|
||||||
{
|
|
||||||
if (_piid != -1) {
|
|
||||||
IntervalManager.remove(_piid);
|
|
||||||
_piid = -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reads a new message from the socket (blocking until a message has
|
* Reads a new message from the socket (blocking until a message has
|
||||||
* arrived).
|
* arrived).
|
||||||
@@ -600,7 +571,6 @@ public class Communicator
|
|||||||
protected SocketChannel _channel;
|
protected SocketChannel _channel;
|
||||||
protected Queue _msgq = new Queue();
|
protected Queue _msgq = new Queue();
|
||||||
|
|
||||||
protected int _piid = -1;
|
|
||||||
protected long _lastWrite;
|
protected long _lastWrite;
|
||||||
|
|
||||||
/** We use this to frame our upstream messages. */
|
/** We use this to frame our upstream messages. */
|
||||||
|
|||||||
Reference in New Issue
Block a user