diff --git a/docs/presents/notes.txt b/docs/presents/notes.txt index 99f46f20f..69cc61ee1 100644 --- a/docs/presents/notes.txt +++ b/docs/presents/notes.txt @@ -1,5 +1,16 @@ Cher Mk3 Notes -*- outline -*- +* Server-side event concentrator +The client objects will not subscribe directly, but will subscribe through +the concentrator so that, at least, it can create a single +ForwardEventNotification for each Event being dispatched to a group of +clients. Optimally, it would be able to flatten that notification as well +and the byte array can be written to the socket of each of the individual +clients rather than creating a separate byte array for each client. This +will require a special "flattened notification" that can be inserted into +the queue to preserve message ordering but then is simply sent rather than +flattened and sent. + * Marshaller Consider how the dobject marshaller deals with classes loaded and reloaded using flushable classloaders. diff --git a/src/java/com/threerings/presents/dobj/AttributesChangedEvent.java b/src/java/com/threerings/presents/dobj/AttributesChangedEvent.java index 357b8fd4c..56472fc45 100644 --- a/src/java/com/threerings/presents/dobj/AttributesChangedEvent.java +++ b/src/java/com/threerings/presents/dobj/AttributesChangedEvent.java @@ -1,5 +1,5 @@ // -// $Id: AttributesChangedEvent.java,v 1.1 2001/06/01 07:12:13 mdb Exp $ +// $Id: AttributesChangedEvent.java,v 1.2 2001/06/02 01:30:37 mdb Exp $ package com.threerings.cocktail.cher.dobj; @@ -139,6 +139,19 @@ public class AttributesChangedEvent extends DEvent return ((Double)_values[index]).doubleValue(); } + /** + * Applies this attribute change to the object. + */ + public boolean applyToObject (DObject target) + throws ObjectAccessException + { + // pass the new values on to the object + for (int i = 0; i < _count; i++) { + target.setAttribute(_names[i], _values[i]); + } + return true; + } + protected int _count; protected String[] _names; protected Object[] _values; diff --git a/src/java/com/threerings/presents/dobj/Subscriber.java b/src/java/com/threerings/presents/dobj/Subscriber.java index 2d854bf91..cfdcd5ba7 100644 --- a/src/java/com/threerings/presents/dobj/Subscriber.java +++ b/src/java/com/threerings/presents/dobj/Subscriber.java @@ -1,5 +1,5 @@ // -// $Id: Subscriber.java,v 1.2 2001/06/01 05:17:16 mdb Exp $ +// $Id: Subscriber.java,v 1.3 2001/06/02 01:30:37 mdb Exp $ package com.threerings.cocktail.cher.dobj; @@ -34,7 +34,7 @@ public interface Subscriber * @see DObjectManager.subscribeToObject * @see DObjectManager.fetchObject */ - public void requestFailed (ObjectAccessException cause); + public void requestFailed (int oid, ObjectAccessException cause); /** * Called when an event has been dispatched on an object. The event diff --git a/src/java/com/threerings/presents/net/AuthRequest.java b/src/java/com/threerings/presents/net/AuthRequest.java index f53827e01..e5da35623 100644 --- a/src/java/com/threerings/presents/net/AuthRequest.java +++ b/src/java/com/threerings/presents/net/AuthRequest.java @@ -1,5 +1,5 @@ // -// $Id: AuthRequest.java,v 1.4 2001/05/30 23:58:31 mdb Exp $ +// $Id: AuthRequest.java,v 1.5 2001/06/02 01:30:37 mdb Exp $ package com.threerings.cocktail.cher.net; @@ -35,6 +35,11 @@ public class AuthRequest extends UpstreamMessage return TYPE; } + public Credentials getCredentials () + { + return _creds; + } + public void writeTo (DataOutputStream out) throws IOException { diff --git a/src/java/com/threerings/presents/net/Credentials.java b/src/java/com/threerings/presents/net/Credentials.java index de5b09624..69b04de65 100644 --- a/src/java/com/threerings/presents/net/Credentials.java +++ b/src/java/com/threerings/presents/net/Credentials.java @@ -1,5 +1,5 @@ // -// $Id: Credentials.java,v 1.4 2001/05/30 23:58:31 mdb Exp $ +// $Id: Credentials.java,v 1.5 2001/06/02 01:30:37 mdb Exp $ package com.threerings.cocktail.cher.net; @@ -14,8 +14,11 @@ import com.threerings.cocktail.cher.io.TypedObjectFactory; * Credentials are supplied by the client implementation and sent along to * the server during the authentication process. To provide support for a * variety of authentication methods, the credentials class is meant to be - * subclassed for the particular method (ie. username + password) in use - * in a given system. + * subclassed for the particular method (ie. password, auth digest, etc.) + * in use in a given system. + * + *

All credentials must provide a username as the username is used to + * associate network connections with sessions. * *

All derived classes should provide a no argument constructor so * that they can be instantiated prior to reconstruction from a data input @@ -29,6 +32,27 @@ public abstract class Credentials implements TypedObject */ public static final short TYPE_BASE = 300; + /** + * Constructs a credentials instance with the specified username. + */ + public Credentials (String username) + { + _username = username; + } + + /** + * Constructs a blank credentials instance in preparation for + * unserializing from the network. + */ + public Credentials () + { + } + + public String getUsername () + { + return _username; + } + /** * Derived classes should override this function to write their fields * out to the supplied data output stream. They must be sure @@ -37,7 +61,7 @@ public abstract class Credentials implements TypedObject public void writeTo (DataOutputStream out) throws IOException { - // we don't do anything here, but we may want to some day + out.writeUTF(_username); } /** @@ -48,6 +72,8 @@ public abstract class Credentials implements TypedObject public void readFrom (DataInputStream in) throws IOException { - // we don't do anything here, but we may want to some day + _username = in.readUTF(); } + + protected String _username; } diff --git a/src/java/com/threerings/presents/net/EventNotification.java b/src/java/com/threerings/presents/net/EventNotification.java index d9c44d4cf..b5c54b5e8 100644 --- a/src/java/com/threerings/presents/net/EventNotification.java +++ b/src/java/com/threerings/presents/net/EventNotification.java @@ -1,5 +1,5 @@ // -// $Id: EventNotification.java,v 1.4 2001/05/30 23:59:16 mdb Exp $ +// $Id: EventNotification.java,v 1.5 2001/06/02 01:30:37 mdb Exp $ package com.threerings.cocktail.cher.net; @@ -7,7 +7,7 @@ import java.io.IOException; import java.io.DataInputStream; import java.io.DataOutputStream; -import com.threerings.cocktail.cher.dobj.Event; +import com.threerings.cocktail.cher.dobj.DEvent; public class EventNotification extends DownstreamMessage { @@ -25,7 +25,7 @@ public class EventNotification extends DownstreamMessage /** * Constructs an event notification for the supplied event. */ - public EventNotification (Event event) + public EventNotification (DEvent event) { _event = event; } @@ -50,5 +50,5 @@ public class EventNotification extends DownstreamMessage } /** The event which we are forwarding. */ - protected Event _event; + protected DEvent _event; } diff --git a/src/java/com/threerings/presents/net/FailureResponse.java b/src/java/com/threerings/presents/net/FailureResponse.java index d3d0e40c0..6aa78933b 100644 --- a/src/java/com/threerings/presents/net/FailureResponse.java +++ b/src/java/com/threerings/presents/net/FailureResponse.java @@ -1,5 +1,5 @@ // -// $Id: FailureResponse.java,v 1.2 2001/05/30 23:58:31 mdb Exp $ +// $Id: FailureResponse.java,v 1.3 2001/06/02 01:30:37 mdb Exp $ package com.threerings.cocktail.cher.net; @@ -21,12 +21,12 @@ public class FailureResponse extends DownstreamMessage } /** - * Constructs a failure response that is associated with the specified - * upstream message id. + * Constructs a failure response in response to a request for the + * specified oid. */ - public FailureResponse (short messageId) + public FailureResponse (int oid) { - this.messageId = messageId; + _oid = oid; } public short getType () @@ -34,17 +34,24 @@ public class FailureResponse extends DownstreamMessage return TYPE; } + public int getOid () + { + return _oid; + } + public void writeTo (DataOutputStream out) throws IOException { super.writeTo(out); - out.writeShort(messageId); + out.writeInt(_oid); } public void readFrom (DataInputStream in) throws IOException { super.readFrom(in); - messageId = in.readShort(); + _oid = in.readInt(); } + + protected int _oid; } diff --git a/src/java/com/threerings/presents/net/ObjectResponse.java b/src/java/com/threerings/presents/net/ObjectResponse.java index fc1014b58..ca32017c1 100644 --- a/src/java/com/threerings/presents/net/ObjectResponse.java +++ b/src/java/com/threerings/presents/net/ObjectResponse.java @@ -1,5 +1,5 @@ // -// $Id: ObjectResponse.java,v 1.5 2001/05/30 23:58:31 mdb Exp $ +// $Id: ObjectResponse.java,v 1.6 2001/06/02 01:30:37 mdb Exp $ package com.threerings.cocktail.cher.net; @@ -24,12 +24,10 @@ public class ObjectResponse extends DownstreamMessage } /** - * Constructs an object response with supplied distributed object that - * is associated with the specified upstream message id. + * Constructs an object response with supplied distributed object. */ - public ObjectResponse (short messageId, DObject dobj) + public ObjectResponse (DObject dobj) { - this.messageId = messageId; _dobj = dobj; } @@ -42,7 +40,6 @@ public class ObjectResponse extends DownstreamMessage throws IOException { super.writeTo(out); - out.writeShort(messageId); DObjectFactory.writeTo(out, _dobj); } @@ -50,7 +47,6 @@ public class ObjectResponse extends DownstreamMessage throws IOException { super.readFrom(in); - messageId = in.readShort(); _dobj = (DObject)DObjectFactory.readFrom(in); } diff --git a/src/java/com/threerings/presents/net/UsernamePasswordCreds.java b/src/java/com/threerings/presents/net/UsernamePasswordCreds.java index f67a8cf3e..257961515 100644 --- a/src/java/com/threerings/presents/net/UsernamePasswordCreds.java +++ b/src/java/com/threerings/presents/net/UsernamePasswordCreds.java @@ -1,5 +1,5 @@ // -// $Id: UsernamePasswordCreds.java,v 1.4 2001/05/30 23:58:31 mdb Exp $ +// $Id: UsernamePasswordCreds.java,v 1.5 2001/06/02 01:30:37 mdb Exp $ package com.threerings.cocktail.cher.net; @@ -24,7 +24,7 @@ public class UsernamePasswordCreds extends Credentials */ public UsernamePasswordCreds (String username, String password) { - _username = username; + super(username); _password = password; } @@ -33,11 +33,15 @@ public class UsernamePasswordCreds extends Credentials return TYPE; } + public String getPassword () + { + return _password; + } + public void writeTo (DataOutputStream out) throws IOException { super.writeTo(out); - out.writeUTF(_username); out.writeUTF(_password); } @@ -45,10 +49,13 @@ public class UsernamePasswordCreds extends Credentials throws IOException { super.readFrom(in); - _username = in.readUTF(); _password = in.readUTF(); } - protected String _username; + public String toString () + { + return "[username=" + _username + ", password=" + _password + "]"; + } + protected String _password; } diff --git a/src/java/com/threerings/presents/server/ClientManager.java b/src/java/com/threerings/presents/server/ClientManager.java index ec5fc9af5..4e89922ef 100644 --- a/src/java/com/threerings/presents/server/ClientManager.java +++ b/src/java/com/threerings/presents/server/ClientManager.java @@ -1,11 +1,13 @@ // -// $Id: ClientManager.java,v 1.1 2001/06/01 22:12:03 mdb Exp $ +// $Id: ClientManager.java,v 1.2 2001/06/02 01:30:37 mdb Exp $ package com.threerings.cocktail.cher.server; import java.io.IOException; +import java.util.HashMap; import com.threerings.cocktail.cher.Log; +import com.threerings.cocktail.cher.net.Credentials; import com.threerings.cocktail.cher.server.net.*; /** @@ -13,6 +15,11 @@ import com.threerings.cocktail.cher.server.net.*; * surprise) which are slightly more than just connections. Clients * persist in the absence of connections in case a user goes bye bye * unintentionally and wants to reconnect and continue their session. + * + *

The client manager operates with thread safety because it is called + * both from the conmgr thread (to notify of connections showing up or + * going away) and from the dobjmgr thread (when clients are given the + * boot for application-defined reasons). */ public class ClientManager implements ConnectionObserver { @@ -29,9 +36,22 @@ public class ClientManager implements ConnectionObserver * * @param conn The newly established connection. */ - public void connectionEstablished (Connection conn) + public synchronized + void connectionEstablished (Connection conn, Credentials creds) { - Log.info("Connection established: " + conn); + String username = creds.getUsername(); + + // see if there's a client already registered with this username + Client client = (Client)_clients.get(username); + + if (client != null) { + Log.info("Session resumed [username=" + username + + ", conn=" + conn + "]."); + + } else { + Log.info("Session initiated [username=" + username + + ", conn=" + conn + "]."); + } } /** @@ -43,7 +63,8 @@ public class ClientManager implements ConnectionObserver * @param conn The connection in that failed. * @param fault The exception associated with the failure. */ - public void connectionFailed (Connection conn, IOException fault) + public synchronized + void connectionFailed (Connection conn, IOException fault) { Log.info("Connection failed: " + conn + ": " + fault); } @@ -53,8 +74,10 @@ public class ClientManager implements ConnectionObserver * * @param conn The recently closed connection. */ - public void connectionClosed (Connection conn) + public synchronized void connectionClosed (Connection conn) { Log.info("Connection closed: " + conn); } + + protected HashMap _clients = new HashMap(); } diff --git a/src/java/com/threerings/presents/server/PresentsClient.java b/src/java/com/threerings/presents/server/PresentsClient.java new file mode 100644 index 000000000..94021a428 --- /dev/null +++ b/src/java/com/threerings/presents/server/PresentsClient.java @@ -0,0 +1,97 @@ +// +// $Id: PresentsClient.java,v 1.1 2001/06/02 01:30:37 mdb Exp $ + +package com.threerings.cocktail.cher.server; + +import com.threerings.cocktail.cher.Log; +import com.threerings.cocktail.cher.dobj.*; +import com.threerings.cocktail.cher.net.*; +import com.threerings.cocktail.cher.server.net.*; + +/** + * A client object represents a client session in the server. It is + * associated with a connection instance (while the client is connected) + * and acts as the intermediary for the remote client in terms of passing + * along events forwarded by the client, ensuring that subscriptions are + * maintained on behalf of the client and that events are forwarded to the + * client. + * + *

A note on synchronization: the client object is structured + * so that its Subscriber implementation (which is called + * from the dobjmgr thread) can proceed without synchronization. This does + * not overlap with its other client duties which are called from the + * conmgr thread and therefore also need not be synchronized. + */ +public class Client implements Subscriber, MessageHandler +{ + /** + * Constructs a new client instance bound to the specified username + * and initially associated with the specified connection instance. + */ + public Client (String username, Connection conn) + { + _username = username; + setConnection(conn); + } + + /** + * Called by the client manager when a new connection arrives that + * authenticates as this already established client. This must only be + * called from the congmr thread. + */ + public void resumeSession (Connection conn) + { + // check to see if we've already got a connection object, in which + // case it's probably stale + if (_conn != null) { + Log.info("Closing stale connection [old=" + _conn + + ", new=" + conn + "]."); + // close the old connection (which results in everything being + // properly unregistered) + _conn.close(); + } + + // start using the new connection + setConnection(conn); + + Log.info("Session resumed [client=" + this + "]."); + } + + protected void setConnection (Connection conn) + { + // keep a handle to the new connection + _conn = conn; + + // tell the connection to pass messages on to us + _conn.setMessageHandler(this); + } + + // documentation inherited from interface + public void handleMessage (UpstreamMessage message) + { + } + + // documentation inherited from interface + public void objectAvailable (DObject object) + { + // queue up an object response + _conn.postMessage(new ObjectResponse(object)); + } + + // documentation inherited from interface + public void requestFailed (int oid, ObjectAccessException cause) + { + _conn.postMessage(new FailureResponse(oid)); + } + + // documentation inherited from interface + public boolean handleEvent (DEvent event, DObject target) + { + // forward the event to the client + _conn.postMessage(new EventNotification(event)); + return true; + } + + protected String _username; + protected transient Connection _conn; +} diff --git a/src/java/com/threerings/presents/server/PresentsDObjectMgr.java b/src/java/com/threerings/presents/server/PresentsDObjectMgr.java index f6dfaf4c5..c6c0d9a4e 100644 --- a/src/java/com/threerings/presents/server/PresentsDObjectMgr.java +++ b/src/java/com/threerings/presents/server/PresentsDObjectMgr.java @@ -1,5 +1,5 @@ // -// $Id: PresentsDObjectMgr.java,v 1.2 2001/06/01 20:35:39 mdb Exp $ +// $Id: PresentsDObjectMgr.java,v 1.3 2001/06/02 01:30:37 mdb Exp $ package com.threerings.cocktail.cher.server; @@ -175,10 +175,11 @@ public class CherDObjectMgr implements DObjectManager public boolean applyToObject (DObject target) throws ObjectAccessException { + int oid = getNextOid(); + try { // create a new instance of this object DObject obj = (DObject)_class.newInstance(); - int oid = getNextOid(); // initialize this object obj.init(oid, CherDObjectMgr.this); @@ -205,7 +206,8 @@ public class CherDObjectMgr implements DObjectManager // let the subscriber know shit be fucked if (_target != null) { String errmsg = "Object instantiation failed: " + e; - _target.requestFailed(new ObjectAccessException(errmsg)); + _target.requestFailed( + oid, new ObjectAccessException(errmsg)); } } @@ -243,14 +245,14 @@ public class CherDObjectMgr implements DObjectManager // if it don't exist, let them know if (obj == null) { - _target.requestFailed(new NoSuchObjectException(_oid)); + _target.requestFailed(_oid, new NoSuchObjectException(_oid)); return false; } // check permissions if (!obj.checkPermissions(_target)) { String errmsg = "m.access_denied\t" + _oid; - _target.requestFailed(new ObjectAccessException(errmsg)); + _target.requestFailed(_oid, new ObjectAccessException(errmsg)); return false; } diff --git a/src/java/com/threerings/presents/server/net/AuthingConnection.java b/src/java/com/threerings/presents/server/net/AuthingConnection.java index dbc2e8468..47406b3a2 100644 --- a/src/java/com/threerings/presents/server/net/AuthingConnection.java +++ b/src/java/com/threerings/presents/server/net/AuthingConnection.java @@ -1,5 +1,5 @@ // -// $Id: AuthingConnection.java,v 1.2 2001/05/30 23:58:31 mdb Exp $ +// $Id: AuthingConnection.java,v 1.3 2001/06/02 01:30:37 mdb Exp $ package com.threerings.cocktail.cher.server.net; @@ -14,7 +14,8 @@ import com.threerings.cocktail.cher.net.AuthRequest; * The authing connection manages the client connection until * authentication has completed (for better or for worse). */ -public class AuthingConnection extends Connection +public class AuthingConnection + extends Connection implements MessageHandler { /** * Creates a new authing connection object that will manage the @@ -25,6 +26,8 @@ public class AuthingConnection extends Connection throws IOException { super(cmgr, socket); + // we are our own message handler + setMessageHandler(this); } /** @@ -55,6 +58,11 @@ public class AuthingConnection extends Connection return _authreq; } + public String toString () + { + return "[mode=AUTHING, addr=" + _socket.getInetAddress() + "]"; + } + protected int _state = AWAITING_AUTH_REQUEST; protected AuthRequest _authreq; diff --git a/src/java/com/threerings/presents/server/net/Connection.java b/src/java/com/threerings/presents/server/net/Connection.java index 82be5235e..37666f613 100644 --- a/src/java/com/threerings/presents/server/net/Connection.java +++ b/src/java/com/threerings/presents/server/net/Connection.java @@ -1,5 +1,5 @@ // -// $Id: Connection.java,v 1.3 2001/06/01 22:12:03 mdb Exp $ +// $Id: Connection.java,v 1.4 2001/06/02 01:30:37 mdb Exp $ package com.threerings.cocktail.cher.server.net; @@ -45,6 +45,16 @@ public abstract class Connection implements NetEventHandler _din = new DataInputStream(_fin); } + /** + * Instructs the connection to pass parsed messages on to this handler + * for processing. This should be done before the connection is turned + * loose to process messages. + */ + public void setMessageHandler (MessageHandler handler) + { + _handler = handler; + } + /** * Returns the select item associated with this connection. */ @@ -71,6 +81,33 @@ public abstract class Connection implements NetEventHandler return _socket; } + /** + * Closes this connection and unregisters it from the connection + * manager. This should only be called from the conmgr thread. + */ + public void close () + { + // we shouldn't be closed twice + if (_socket == null) { + Log.warning("Attempted to re-close connection."); + return; + } + + // unregister from the select set + _cmgr.connectionClosed(this); + + // close our socket + try { + _socket.close(); + } catch (IOException ioe) { + Log.warning("Error closing connection [conn=" + this + + ", error=" + ioe + "]."); + } + + // clear out our socket reference to prevent repeat closings + _socket = null; + } + /** * Called when our client socket has data available for reading. */ @@ -80,8 +117,8 @@ public abstract class Connection implements NetEventHandler // read the available data and see if we have a whole frame if (_fin.readFrame(_in)) { // parse the message and pass it on - handleMessage((UpstreamMessage) - TypedObjectFactory.readFrom(_din)); + _handler.handleMessage((UpstreamMessage) + TypedObjectFactory.readFrom(_din)); } } catch (EOFException eofe) { @@ -96,12 +133,6 @@ public abstract class Connection implements NetEventHandler } } - /** - * Called when a complete message has been parsed from incoming - * network data. - */ - public abstract void handleMessage (UpstreamMessage msg); - /** * Posts a downstream message for delivery to this connection. The * message will be delivered by the conmgr thread as soon as it gets @@ -121,4 +152,6 @@ public abstract class Connection implements NetEventHandler protected OutputStream _out; protected FramedInputStream _fin; protected DataInputStream _din; + + protected MessageHandler _handler; } diff --git a/src/java/com/threerings/presents/server/net/ConnectionManager.java b/src/java/com/threerings/presents/server/net/ConnectionManager.java index 244b6c95a..071c4004d 100644 --- a/src/java/com/threerings/presents/server/net/ConnectionManager.java +++ b/src/java/com/threerings/presents/server/net/ConnectionManager.java @@ -1,5 +1,5 @@ // -// $Id: ConnectionManager.java,v 1.3 2001/06/01 22:12:03 mdb Exp $ +// $Id: ConnectionManager.java,v 1.4 2001/06/02 01:30:37 mdb Exp $ package com.threerings.cocktail.cher.server.net; @@ -15,6 +15,7 @@ import com.samskivert.util.Queue; import com.threerings.cocktail.cher.Log; import com.threerings.cocktail.cher.io.FramingOutputStream; import com.threerings.cocktail.cher.io.TypedObjectFactory; +import com.threerings.cocktail.cher.net.Credentials; import com.threerings.cocktail.cher.net.DownstreamMessage; import com.threerings.cocktail.cher.net.Registry; @@ -102,8 +103,7 @@ public class ConnectionManager extends LoopingThread * Notifies the connection observers of a connection event. Used * internally. */ - protected void notifyObservers (int code, Connection conn, - IOException cause) + protected void notifyObservers (int code, Connection conn, Object arg) { synchronized (_observers) { for (int i = 0; i < _observers.size(); i++) { @@ -111,10 +111,10 @@ public class ConnectionManager extends LoopingThread (ConnectionObserver)_observers.get(i); switch (code) { case CONNECTION_ESTABLISHED: - obs.connectionEstablished(conn); + obs.connectionEstablished(conn, (Credentials)arg); break; case CONNECTION_FAILED: - obs.connectionFailed(conn, cause); + obs.connectionFailed(conn, (IOException)arg); break; case CONNECTION_CLOSED: obs.connectionClosed(conn); @@ -154,8 +154,8 @@ public class ConnectionManager extends LoopingThread } // check for connections that have completed authentication - Connection conn; - while ((conn = (Connection)_authq.getNonBlocking()) != null) { + AuthingConnection conn; + while ((conn = (AuthingConnection)_authq.getNonBlocking()) != null) { // remove the old connection from the select set _selset.remove(conn.getSelectItem()); @@ -168,7 +168,8 @@ public class ConnectionManager extends LoopingThread _selset.add(rconn.getSelectItem()); // and let our observers know about our new connection - notifyObservers(CONNECTION_ESTABLISHED, rconn, null); + notifyObservers(CONNECTION_ESTABLISHED, rconn, + conn.getAuthRequest().getCredentials()); } catch (IOException ioe) { Log.warning("Failure upgrading authing connection to " + diff --git a/src/java/com/threerings/presents/server/net/ConnectionObserver.java b/src/java/com/threerings/presents/server/net/ConnectionObserver.java index 950f83907..539323e17 100644 --- a/src/java/com/threerings/presents/server/net/ConnectionObserver.java +++ b/src/java/com/threerings/presents/server/net/ConnectionObserver.java @@ -1,9 +1,10 @@ // -// $Id: ConnectionObserver.java,v 1.3 2001/06/01 22:12:03 mdb Exp $ +// $Id: ConnectionObserver.java,v 1.4 2001/06/02 01:30:37 mdb Exp $ package com.threerings.cocktail.cher.server.net; import java.io.IOException; +import com.threerings.cocktail.cher.net.Credentials; /** * A connection observer can be registered with the connection manager to @@ -23,8 +24,10 @@ public interface ConnectionObserver * the connection observer. * * @param conn The newly established connection. + * @param creds The credentials with which this connection + * (successfully) authenticated. */ - public void connectionEstablished (Connection conn); + public void connectionEstablished (Connection conn, Credentials creds); /** * Called if a connection fails for any reason. If a connection fails, diff --git a/src/java/com/threerings/presents/server/net/MessageHandler.java b/src/java/com/threerings/presents/server/net/MessageHandler.java new file mode 100644 index 000000000..0c7de45fa --- /dev/null +++ b/src/java/com/threerings/presents/server/net/MessageHandler.java @@ -0,0 +1,19 @@ +// +// $Id: MessageHandler.java,v 1.1 2001/06/02 01:30:37 mdb Exp $ + +package com.threerings.cocktail.cher.server.net; + +import com.threerings.cocktail.cher.net.UpstreamMessage; + +/** + * After the connection object has parsed an entire upstream message, it + * passes it on to its message handler. + */ +public interface MessageHandler +{ + /** + * Called when a complete message has been parsed from incoming + * network data. + */ + public void handleMessage (UpstreamMessage message); +} diff --git a/src/java/com/threerings/presents/server/net/RunningConnection.java b/src/java/com/threerings/presents/server/net/RunningConnection.java index 62bac1562..cc5a22a3f 100644 --- a/src/java/com/threerings/presents/server/net/RunningConnection.java +++ b/src/java/com/threerings/presents/server/net/RunningConnection.java @@ -1,5 +1,5 @@ // -// $Id: RunningConnection.java,v 1.2 2001/05/30 23:58:31 mdb Exp $ +// $Id: RunningConnection.java,v 1.3 2001/06/02 01:30:37 mdb Exp $ package com.threerings.cocktail.cher.server.net; @@ -30,4 +30,9 @@ public class RunningConnection extends Connection public void handleMessage (UpstreamMessage msg) { } + + public String toString () + { + return "[mode=RUNNING, addr=" + _socket.getInetAddress() + "]"; + } }