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() + "]";
+ }
}