diff --git a/src/java/com/threerings/presents/client/BlockingCommunicator.java b/src/java/com/threerings/presents/client/BlockingCommunicator.java index 02536cae8..f29a0e40b 100644 --- a/src/java/com/threerings/presents/client/BlockingCommunicator.java +++ b/src/java/com/threerings/presents/client/BlockingCommunicator.java @@ -398,8 +398,9 @@ public class BlockingCommunicator extends Communicator if (wrote != buffer.limit()) { log.warning("Aiya! Couldn't write entire message", "msg", msg, "size", buffer.limit(), "wrote", wrote); -// } else { + } else { // Log.info("Wrote " + wrote + " bytes."); + _client.getMessageTracker().messageSent(false, wrote, msg); } } finally { @@ -443,6 +444,9 @@ public class BlockingCommunicator extends Communicator // send the datagram _datagramChannel.write(buf); + + // notify the tracker + _client.getMessageTracker().messageSent(true, size, msg); } /** @@ -460,10 +464,12 @@ public class BlockingCommunicator extends Communicator } try { + int size = _fin.available(); DownstreamMessage msg = (DownstreamMessage)_oin.readObject(); if (debugLogMessages()) { log.info("RECEIVE " + msg); } + _client.getMessageTracker().messageReceived(false, size, msg); return msg; } catch (ClassNotFoundException cnfe) { @@ -480,7 +486,8 @@ public class BlockingCommunicator extends Communicator { // clear the buffer and read a datagram _buf.clear(); - if (_datagramChannel.read(_buf) <= 0) { + int size = _datagramChannel.read(_buf); + if (size <= 0) { throw new IOException("No datagram available to read."); } _buf.flip(); @@ -494,6 +501,7 @@ public class BlockingCommunicator extends Communicator if (debugLogMessages()) { log.info("DATAGRAM " + msg); } + _client.getMessageTracker().messageReceived(true, size, msg); return msg; } catch (ClassNotFoundException cnfe) { diff --git a/src/java/com/threerings/presents/client/Client.java b/src/java/com/threerings/presents/client/Client.java index c033e5f6d..14444f633 100644 --- a/src/java/com/threerings/presents/client/Client.java +++ b/src/java/com/threerings/presents/client/Client.java @@ -227,6 +227,17 @@ public class Client } } + /** + * Installs (or clears) a message tracker that will be notified on message transmission and + * receipt for the purpose of statistics tracking. + * + * @param tracker the new tracker to install, or null to clear the tracker. + */ + public void setMessageTracker (MessageTracker tracker) + { + _messageTracker = (tracker == null) ? MessageTracker.NOOP : tracker; + } + /** * Returns the data associated with our authentication response. Users of the Presents system * may wish to communicate authentication related information to their client by extending and @@ -676,6 +687,14 @@ public class Client return _outThrottle; } + /** + * Returns a reference to the message tracker to notify on message transmission and receipt. + */ + protected MessageTracker getMessageTracker () + { + return _messageTracker; + } + /** * 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. @@ -1028,6 +1047,9 @@ public class Client /** Our outgoing message throttle. */ protected Throttle _outThrottle = new Throttle(DEFAULT_MSGS_PER_SECOND, 1000L); + /** The tracker to notify on message transmission or receipt. */ + protected volatile MessageTracker _messageTracker = MessageTracker.NOOP; + /** How often we recompute our time offset from the server. */ protected static final long CLOCK_SYNC_INTERVAL = 600 * 1000L; } diff --git a/src/java/com/threerings/presents/client/MessageTracker.java b/src/java/com/threerings/presents/client/MessageTracker.java new file mode 100644 index 000000000..7684c32df --- /dev/null +++ b/src/java/com/threerings/presents/client/MessageTracker.java @@ -0,0 +1,52 @@ +// +// $Id$ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2009 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// This library is free software; you can redistribute it and/or modify it +// under the terms of the GNU Lesser General Public License as published +// by the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.presents.client; + +import com.threerings.presents.net.DownstreamMessage; +import com.threerings.presents.net.UpstreamMessage; + +/** + * Used to listen to low-level message handling for the purpose of statistics tracking. Methods + * must be thread-safe. + */ +public interface MessageTracker +{ + /** + * An implementation of the interface that does nothing. + */ + public static final MessageTracker NOOP = new MessageTracker() { + public void messageSent (boolean datagram, int size, UpstreamMessage msg) { + } + public void messageReceived (boolean datagram, int size, DownstreamMessage msg) { + } + }; + + /** + * Notes that a message has been sent. + */ + public void messageSent (boolean datagram, int size, UpstreamMessage msg); + + /** + * Notes that a message has been received. + */ + public void messageReceived (boolean datagram, int size, DownstreamMessage msg); +}