Added code to establish the time delta between the client and server
clocks immediately following authentication. git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@1398 542714f4-19e9-0310-aa3c-eee0fc999fb1
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// $Id: Client.java,v 1.22 2002/04/10 06:08:59 mdb Exp $
|
// $Id: Client.java,v 1.23 2002/05/28 21:56:38 mdb Exp $
|
||||||
|
|
||||||
package com.threerings.presents.client;
|
package com.threerings.presents.client;
|
||||||
|
|
||||||
@@ -13,6 +13,8 @@ import com.threerings.presents.data.ClientObject;
|
|||||||
import com.threerings.presents.dobj.DObjectManager;
|
import com.threerings.presents.dobj.DObjectManager;
|
||||||
import com.threerings.presents.net.BootstrapData;
|
import com.threerings.presents.net.BootstrapData;
|
||||||
import com.threerings.presents.net.Credentials;
|
import com.threerings.presents.net.Credentials;
|
||||||
|
import com.threerings.presents.net.PingRequest;
|
||||||
|
import com.threerings.presents.net.PongResponse;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Through the client object, a connection to the system is established
|
* Through the client object, a connection to the system is established
|
||||||
@@ -202,6 +204,28 @@ public class Client
|
|||||||
return _bstrap;
|
return _bstrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts a server time stamp to a value comparable to client clock
|
||||||
|
* readings.
|
||||||
|
*/
|
||||||
|
public long fromServerTime (long stamp)
|
||||||
|
{
|
||||||
|
// when we calcuated our time delta, we did it such that: C - S =
|
||||||
|
// dT, thus to convert server to client time we do: C = S + dT
|
||||||
|
return stamp + _serverDelta;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts a server tick stamp (which is the number of milliseconds
|
||||||
|
* since the server started up) to an absolute client timestamp.
|
||||||
|
*/
|
||||||
|
public long fromServerTicks (int ticks)
|
||||||
|
{
|
||||||
|
// we already have our adjusted server start stamp, so we just add
|
||||||
|
// the milliseconds since that time to get absolute time
|
||||||
|
return _serverStartStamp + ticks;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if we are logged on, false if we're not.
|
* Returns true if we are logged on, false if we're not.
|
||||||
*/
|
*/
|
||||||
@@ -263,6 +287,50 @@ public class Client
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 ()
|
||||||
|
{
|
||||||
|
// create a new delta calculator and start the process
|
||||||
|
_dcalc = new DeltaCalculator();
|
||||||
|
PingRequest req = new PingRequest();
|
||||||
|
_comm.postMessage(req);
|
||||||
|
_dcalc.sentPing(req);
|
||||||
|
Log.info("Sent ping.");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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
|
||||||
|
ResultListener rl = new ResultListener() {
|
||||||
|
public void requestCompleted (Object result) {
|
||||||
|
// keep this around
|
||||||
|
_clobj = (ClientObject)result;
|
||||||
|
// let the client know that logon has now fully succeeded
|
||||||
|
notifyObservers(Client.CLIENT_DID_LOGON, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void requestFailed (Exception cause) {
|
||||||
|
// pass the buck onto the listeners
|
||||||
|
notifyObservers(Client.CLIENT_FAILED_TO_LOGON, cause);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
_invdir.init(_comm.getDObjectManager(), _cloid, _bstrap.invOid, rl);
|
||||||
|
|
||||||
|
// 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
|
||||||
|
}
|
||||||
|
|
||||||
boolean notifyObservers (int code, Exception cause)
|
boolean notifyObservers (int code, Exception cause)
|
||||||
{
|
{
|
||||||
boolean rejected = false;
|
boolean rejected = false;
|
||||||
@@ -320,33 +388,65 @@ public class Client
|
|||||||
// extract bootstrap information
|
// extract bootstrap information
|
||||||
_cloid = data.clientOid;
|
_cloid = data.clientOid;
|
||||||
|
|
||||||
// initialize our invocation director
|
// keep track of our server start time
|
||||||
ResultListener rl = new ResultListener() {
|
_serverStartStamp = data.serverStartStamp;
|
||||||
public void requestCompleted (Object result) {
|
|
||||||
// keep this around
|
|
||||||
_clobj = (ClientObject)result;
|
|
||||||
// let the client know that logon has now fully succeeded
|
|
||||||
notifyObservers(Client.CLIENT_DID_LOGON, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void requestFailed (Exception cause) {
|
// send a few pings to the server to establish the clock offset
|
||||||
// pass the buck onto the listeners
|
// between this client and server standard time
|
||||||
notifyObservers(Client.CLIENT_FAILED_TO_LOGON, cause);
|
establishClockDelta();
|
||||||
}
|
|
||||||
};
|
|
||||||
_invdir.init(_comm.getDObjectManager(), _cloid, data.invOid, rl);
|
|
||||||
|
|
||||||
// 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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when we receive a pong packet. We may be in the process of
|
||||||
|
* calculating the client/server time differential, or we may have
|
||||||
|
* already done that at which point we ignore pongs.
|
||||||
|
*/
|
||||||
|
void gotPong (PongResponse pong)
|
||||||
|
{
|
||||||
|
Log.info("Got 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 are calculating, we'll either be sending another ping...
|
||||||
|
if (_dcalc.gotPong(pong)) {
|
||||||
|
PingRequest req = new PingRequest();
|
||||||
|
_comm.postMessage(req);
|
||||||
|
_dcalc.sentPing(req);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// ...or we're done so we can grab the time delta and finish
|
||||||
|
// our business
|
||||||
|
_serverDelta = _dcalc.getTimeDelta();
|
||||||
|
// adjust our server start stamp into client time
|
||||||
|
_serverStartStamp += _serverDelta;
|
||||||
|
// free up our delta calculator
|
||||||
|
_dcalc = null;
|
||||||
|
// let the client continue with its initialization
|
||||||
|
clockDeltaEstablished();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** The credentials we used to authenticate with the server. */
|
||||||
protected Credentials _creds;
|
protected Credentials _creds;
|
||||||
|
|
||||||
|
/** An entity that gives us the ability to process events on the main
|
||||||
|
* client thread (which is also the AWT thread). */
|
||||||
protected Invoker _invoker;
|
protected Invoker _invoker;
|
||||||
|
|
||||||
|
/** Our client distribted object id. */
|
||||||
|
protected int _cloid;
|
||||||
|
|
||||||
|
/** Our client distributed object. */
|
||||||
protected ClientObject _clobj;
|
protected ClientObject _clobj;
|
||||||
|
|
||||||
|
/** The game server host. */
|
||||||
protected String _hostname;
|
protected String _hostname;
|
||||||
|
|
||||||
|
/** The port on which we connect to the game server. */
|
||||||
protected int _port;
|
protected int _port;
|
||||||
|
|
||||||
/** Our list of client observers. */
|
/** Our list of client observers. */
|
||||||
@@ -355,10 +455,24 @@ public class Client
|
|||||||
/** The entity that manages our network communications. */
|
/** The entity that manages our network communications. */
|
||||||
protected Communicator _comm;
|
protected Communicator _comm;
|
||||||
|
|
||||||
|
/** General startup information provided by the server. */
|
||||||
protected BootstrapData _bstrap;
|
protected BootstrapData _bstrap;
|
||||||
protected int _cloid;
|
|
||||||
|
/** Manages invocation services. */
|
||||||
protected InvocationDirector _invdir = new InvocationDirector();
|
protected InvocationDirector _invdir = new InvocationDirector();
|
||||||
|
|
||||||
|
/** The difference between the server clock and the client clock
|
||||||
|
* (estimated immediately after logging on). */
|
||||||
|
protected long _serverDelta;
|
||||||
|
|
||||||
|
/** The time from which server ticks are computed (converted into
|
||||||
|
* client time. */
|
||||||
|
protected long _serverStartStamp;
|
||||||
|
|
||||||
|
/** Used when establishing our clock delta between the client and
|
||||||
|
* server. */
|
||||||
|
protected DeltaCalculator _dcalc;
|
||||||
|
|
||||||
// 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: ClientDObjectMgr.java,v 1.13 2002/02/10 04:19:34 mdb Exp $
|
// $Id: ClientDObjectMgr.java,v 1.14 2002/05/28 21:56:38 mdb Exp $
|
||||||
|
|
||||||
package com.threerings.presents.client;
|
package com.threerings.presents.client;
|
||||||
|
|
||||||
@@ -134,7 +134,7 @@ public class ClientDObjectMgr
|
|||||||
notifyFailure(oid);
|
notifyFailure(oid);
|
||||||
|
|
||||||
} else if (obj instanceof PongResponse) {
|
} else if (obj instanceof PongResponse) {
|
||||||
Log.info("Got pong.");
|
_client.gotPong((PongResponse)obj);
|
||||||
|
|
||||||
} else if (obj instanceof ObjectAction) {
|
} else if (obj instanceof ObjectAction) {
|
||||||
ObjectAction act = (ObjectAction)obj;
|
ObjectAction act = (ObjectAction)obj;
|
||||||
|
|||||||
@@ -0,0 +1,91 @@
|
|||||||
|
//
|
||||||
|
// $Id: DeltaCalculator.java,v 1.1 2002/05/28 21:56:38 mdb Exp $
|
||||||
|
|
||||||
|
package com.threerings.presents.client;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import com.samskivert.util.StringUtil;
|
||||||
|
|
||||||
|
import com.threerings.presents.Log;
|
||||||
|
import com.threerings.presents.net.PingRequest;
|
||||||
|
import com.threerings.presents.net.PongResponse;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to compute the client/server time delta, attempting to account for
|
||||||
|
* the network delay experienced when the server sends its current time to
|
||||||
|
* the client.
|
||||||
|
*/
|
||||||
|
public class DeltaCalculator
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Constructs a delta calculator which is used to calculate the time
|
||||||
|
* delta between the client and server, accounding reasonably well for
|
||||||
|
* the delay introduced by sending a timestamp over the network from
|
||||||
|
* the server to the client.
|
||||||
|
*/
|
||||||
|
public DeltaCalculator ()
|
||||||
|
{
|
||||||
|
_deltas = new long[CLOCK_SYNC_PING_COUNT];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Must be called when a ping message is sent to the server.
|
||||||
|
*/
|
||||||
|
public void sentPing (PingRequest ping)
|
||||||
|
{
|
||||||
|
_ping = ping;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Must be called when the pong response arrives back from the server.
|
||||||
|
*
|
||||||
|
* @return true if we've iterated sufficiently many times to establish
|
||||||
|
* a stable time delta estimate.
|
||||||
|
*/
|
||||||
|
public boolean gotPong (PongResponse pong)
|
||||||
|
{
|
||||||
|
// 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();
|
||||||
|
|
||||||
|
// make a note of when the pong response was sent (in server time)
|
||||||
|
// and the processing delay incurred on the server
|
||||||
|
long server = pong.getPackStamp(), delay = pong.getProcessDelay();
|
||||||
|
|
||||||
|
// compute the network delay (round-trip time divided by two)
|
||||||
|
long nettime = (recv - send - delay)/2;
|
||||||
|
|
||||||
|
// the time delta is the client time when the pong was received
|
||||||
|
// minus the server's send time (plus network delay): dT = C - S
|
||||||
|
_deltas[_iter] = recv - (server + nettime);
|
||||||
|
|
||||||
|
return (++_iter >= CLOCK_SYNC_PING_COUNT);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the best estimate client/server time-delta.
|
||||||
|
*/
|
||||||
|
public long getTimeDelta ()
|
||||||
|
{
|
||||||
|
// sort the estimates and return one from the middle
|
||||||
|
Arrays.sort(_deltas);
|
||||||
|
Log.info("Returning time delta " +
|
||||||
|
"[deltas=" + StringUtil.toString(_deltas) + "].");
|
||||||
|
return _deltas[_deltas.length/2];
|
||||||
|
}
|
||||||
|
|
||||||
|
/** The number of ping/pong iterations we've made. */
|
||||||
|
protected int _iter;
|
||||||
|
|
||||||
|
/** Client/server time delta estimates. */
|
||||||
|
protected long[] _deltas;
|
||||||
|
|
||||||
|
/** A reference to the most recently sent ping which we use to obtain
|
||||||
|
* the appropriate send stamp when we get the corresponding receive
|
||||||
|
* stamp. */
|
||||||
|
protected PingRequest _ping;
|
||||||
|
|
||||||
|
/** The number of times we PING during clock sync to try to smooth out
|
||||||
|
* network jiggling. */
|
||||||
|
protected static final int CLOCK_SYNC_PING_COUNT = 3;
|
||||||
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// $Id: BootstrapData.java,v 1.4 2002/02/04 01:47:20 mdb Exp $
|
// $Id: BootstrapData.java,v 1.5 2002/05/28 21:56:38 mdb Exp $
|
||||||
|
|
||||||
package com.threerings.presents.net;
|
package com.threerings.presents.net;
|
||||||
|
|
||||||
@@ -18,4 +18,7 @@ public class BootstrapData extends DObject
|
|||||||
|
|
||||||
/** The oid to which to send invocation requests. */
|
/** The oid to which to send invocation requests. */
|
||||||
public int invOid;
|
public int invOid;
|
||||||
|
|
||||||
|
/** The time from which server ticks are incrementing. */
|
||||||
|
public long serverStartStamp;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,12 @@
|
|||||||
//
|
//
|
||||||
// $Id: PingRequest.java,v 1.5 2001/10/11 04:07:53 mdb Exp $
|
// $Id: PingRequest.java,v 1.6 2002/05/28 21:56:38 mdb Exp $
|
||||||
|
|
||||||
package com.threerings.presents.net;
|
package com.threerings.presents.net;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.DataInputStream;
|
||||||
|
import java.io.DataOutputStream;
|
||||||
|
|
||||||
public class PingRequest extends UpstreamMessage
|
public class PingRequest extends UpstreamMessage
|
||||||
{
|
{
|
||||||
/** The code for a ping request. */
|
/** The code for a ping request. */
|
||||||
@@ -16,6 +20,46 @@ public class PingRequest extends UpstreamMessage
|
|||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a timestamp that was obtained when this packet was encoded
|
||||||
|
* by the low-level networking code.
|
||||||
|
*/
|
||||||
|
public long getPackStamp ()
|
||||||
|
{
|
||||||
|
return _packStamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a timestamp that was obtained when this packet was decoded
|
||||||
|
* by the low-level networking code.
|
||||||
|
*/
|
||||||
|
public long getUnpackStamp ()
|
||||||
|
{
|
||||||
|
return _unpackStamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
// documentation inherited
|
||||||
|
public void writeTo (DataOutputStream out)
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
|
super.writeTo(out);
|
||||||
|
|
||||||
|
// grab a timestamp noting when we were encoded into a raw buffer
|
||||||
|
// for delivery over the network
|
||||||
|
_packStamp = System.currentTimeMillis();
|
||||||
|
}
|
||||||
|
|
||||||
|
// documentation inherited
|
||||||
|
public void readFrom (DataInputStream in)
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
|
super.readFrom(in);
|
||||||
|
|
||||||
|
// grab a timestamp noting when we were decoded from a raw buffer
|
||||||
|
// after being received over the network
|
||||||
|
_unpackStamp = System.currentTimeMillis();
|
||||||
|
}
|
||||||
|
|
||||||
public short getType ()
|
public short getType ()
|
||||||
{
|
{
|
||||||
return TYPE;
|
return TYPE;
|
||||||
@@ -25,4 +69,12 @@ public class PingRequest extends UpstreamMessage
|
|||||||
{
|
{
|
||||||
return "[type=PING, msgid=" + messageId + "]";
|
return "[type=PING, msgid=" + messageId + "]";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** A time stamp obtained when we serialize this object. */
|
||||||
|
protected long _packStamp;
|
||||||
|
|
||||||
|
/** A time stamp obtained when we unserialize this object (the intent
|
||||||
|
* is to get a timestamp as close as possible to when the packet was
|
||||||
|
* received on the network). */
|
||||||
|
protected long _unpackStamp;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,14 @@
|
|||||||
//
|
//
|
||||||
// $Id: PongResponse.java,v 1.6 2001/10/11 04:07:53 mdb Exp $
|
// $Id: PongResponse.java,v 1.7 2002/05/28 21:56:38 mdb Exp $
|
||||||
|
|
||||||
package com.threerings.presents.net;
|
package com.threerings.presents.net;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.DataInputStream;
|
||||||
|
import java.io.DataOutputStream;
|
||||||
|
|
||||||
|
import com.threerings.presents.Log;
|
||||||
|
|
||||||
public class PongResponse extends DownstreamMessage
|
public class PongResponse extends DownstreamMessage
|
||||||
{
|
{
|
||||||
/** The code for a pong response. */
|
/** The code for a pong response. */
|
||||||
@@ -16,6 +22,82 @@ public class PongResponse extends DownstreamMessage
|
|||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a pong response which will use the supplied ping time to
|
||||||
|
* establish the end-to-end processing delay introduced by the server.
|
||||||
|
*/
|
||||||
|
public PongResponse (long pingStamp)
|
||||||
|
{
|
||||||
|
// save this for when we are serialized in preparation for
|
||||||
|
// delivery over the network
|
||||||
|
_pingStamp = pingStamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the time at which this packet was packed for delivery in
|
||||||
|
* the time frame of the server that sent the packet.
|
||||||
|
*/
|
||||||
|
public long getPackStamp ()
|
||||||
|
{
|
||||||
|
return _packStamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the number of milliseconds that elapsed between the time
|
||||||
|
* that the ping which instigated this pong was read from the network
|
||||||
|
* and the time that this pong was written to the network.
|
||||||
|
*/
|
||||||
|
public int getProcessDelay ()
|
||||||
|
{
|
||||||
|
return _processDelay;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a timestamp that was obtained when this packet was decoded
|
||||||
|
* by the low-level networking code.
|
||||||
|
*/
|
||||||
|
public long getUnpackStamp ()
|
||||||
|
{
|
||||||
|
return _unpackStamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
// documentation inherited
|
||||||
|
public void writeTo (DataOutputStream out)
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
|
super.writeTo(out);
|
||||||
|
|
||||||
|
// make a note of the time at which we were packed
|
||||||
|
_packStamp = System.currentTimeMillis();
|
||||||
|
out.writeLong(_packStamp);
|
||||||
|
|
||||||
|
// the time spent between unpacking the ping and packing the pong
|
||||||
|
// is the processing delay
|
||||||
|
if (_pingStamp == 0L) {
|
||||||
|
Log.warning("Pong response written that was not constructed " +
|
||||||
|
"with a valid ping stamp [rsp=" + this + "].");
|
||||||
|
_processDelay = 0;
|
||||||
|
} else {
|
||||||
|
_processDelay = (int)(_packStamp - _pingStamp);
|
||||||
|
}
|
||||||
|
out.writeInt(_processDelay);
|
||||||
|
}
|
||||||
|
|
||||||
|
// documentation inherited
|
||||||
|
public void readFrom (DataInputStream in)
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
|
super.readFrom(in);
|
||||||
|
|
||||||
|
// grab a timestamp noting when we were decoded from a raw buffer
|
||||||
|
// after being received over the network
|
||||||
|
_unpackStamp = System.currentTimeMillis();
|
||||||
|
|
||||||
|
// read in our time stamps
|
||||||
|
_packStamp = in.readLong();
|
||||||
|
_processDelay = in.readInt();
|
||||||
|
}
|
||||||
|
|
||||||
public short getType ()
|
public short getType ()
|
||||||
{
|
{
|
||||||
return TYPE;
|
return TYPE;
|
||||||
@@ -25,4 +107,23 @@ public class PongResponse extends DownstreamMessage
|
|||||||
{
|
{
|
||||||
return "[type=PONG, msgid=" + messageId + "]";
|
return "[type=PONG, msgid=" + messageId + "]";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** The ping unpack stamp provided at construct time to this pong
|
||||||
|
* response; only valid on the sending process, not the receiving
|
||||||
|
* process. */
|
||||||
|
protected long _pingStamp;
|
||||||
|
|
||||||
|
/** The timestamp obtained immediately before this packet was sent out
|
||||||
|
* over the network. */
|
||||||
|
protected long _packStamp;
|
||||||
|
|
||||||
|
/** The delay in milliseconds between the time that the ping request
|
||||||
|
* was read from the network and the time the pong response was
|
||||||
|
* written to the network. */
|
||||||
|
protected int _processDelay;
|
||||||
|
|
||||||
|
/** A time stamp obtained when we unserialize this object (the intent
|
||||||
|
* is to get a timestamp as close as possible to when the packet was
|
||||||
|
* received on the network). */
|
||||||
|
protected long _unpackStamp;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// $Id: PresentsClient.java,v 1.30 2002/04/26 02:32:27 mdb Exp $
|
// $Id: PresentsClient.java,v 1.31 2002/05/28 21:56:38 mdb Exp $
|
||||||
|
|
||||||
package com.threerings.presents.server;
|
package com.threerings.presents.server;
|
||||||
|
|
||||||
@@ -561,7 +561,8 @@ public class PresentsClient
|
|||||||
// send a pong response
|
// send a pong response
|
||||||
Connection conn = client.getConnection();
|
Connection conn = client.getConnection();
|
||||||
if (conn != null) {
|
if (conn != null) {
|
||||||
conn.postMessage(new PongResponse());
|
PingRequest req = (PingRequest)msg;
|
||||||
|
conn.postMessage(new PongResponse(req.getUnpackStamp()));
|
||||||
} else {
|
} else {
|
||||||
Log.info("Dropped pong response [client=" + client + "].");
|
Log.info("Dropped pong response [client=" + client + "].");
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user