Starting to wire up client/server dobj stuff.
git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@22 542714f4-19e9-0310-aa3c-eee0fc999fb1
This commit is contained in:
@@ -1,5 +1,16 @@
|
|||||||
Cher Mk3 Notes -*- outline -*-
|
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
|
* Marshaller
|
||||||
Consider how the dobject marshaller deals with classes loaded and reloaded
|
Consider how the dobject marshaller deals with classes loaded and reloaded
|
||||||
using flushable classloaders.
|
using flushable classloaders.
|
||||||
|
|||||||
@@ -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;
|
package com.threerings.cocktail.cher.dobj;
|
||||||
|
|
||||||
@@ -139,6 +139,19 @@ public class AttributesChangedEvent extends DEvent
|
|||||||
return ((Double)_values[index]).doubleValue();
|
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 int _count;
|
||||||
protected String[] _names;
|
protected String[] _names;
|
||||||
protected Object[] _values;
|
protected Object[] _values;
|
||||||
|
|||||||
@@ -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;
|
package com.threerings.cocktail.cher.dobj;
|
||||||
|
|
||||||
@@ -34,7 +34,7 @@ public interface Subscriber
|
|||||||
* @see DObjectManager.subscribeToObject
|
* @see DObjectManager.subscribeToObject
|
||||||
* @see DObjectManager.fetchObject
|
* @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
|
* Called when an event has been dispatched on an object. The event
|
||||||
|
|||||||
@@ -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;
|
package com.threerings.cocktail.cher.net;
|
||||||
|
|
||||||
@@ -35,6 +35,11 @@ public class AuthRequest extends UpstreamMessage
|
|||||||
return TYPE;
|
return TYPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Credentials getCredentials ()
|
||||||
|
{
|
||||||
|
return _creds;
|
||||||
|
}
|
||||||
|
|
||||||
public void writeTo (DataOutputStream out)
|
public void writeTo (DataOutputStream out)
|
||||||
throws IOException
|
throws IOException
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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;
|
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
|
* Credentials are supplied by the client implementation and sent along to
|
||||||
* the server during the authentication process. To provide support for a
|
* the server during the authentication process. To provide support for a
|
||||||
* variety of authentication methods, the credentials class is meant to be
|
* variety of authentication methods, the credentials class is meant to be
|
||||||
* subclassed for the particular method (ie. username + password) in use
|
* subclassed for the particular method (ie. password, auth digest, etc.)
|
||||||
* in a given system.
|
* in use in a given system.
|
||||||
|
*
|
||||||
|
* <p> All credentials must provide a username as the username is used to
|
||||||
|
* associate network connections with sessions.
|
||||||
*
|
*
|
||||||
* <p> All derived classes should provide a no argument constructor so
|
* <p> All derived classes should provide a no argument constructor so
|
||||||
* that they can be instantiated prior to reconstruction from a data input
|
* 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;
|
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
|
* Derived classes should override this function to write their fields
|
||||||
* out to the supplied data output stream. They <em>must</em> be sure
|
* out to the supplied data output stream. They <em>must</em> be sure
|
||||||
@@ -37,7 +61,7 @@ public abstract class Credentials implements TypedObject
|
|||||||
public void writeTo (DataOutputStream out)
|
public void writeTo (DataOutputStream out)
|
||||||
throws IOException
|
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)
|
public void readFrom (DataInputStream in)
|
||||||
throws IOException
|
throws IOException
|
||||||
{
|
{
|
||||||
// we don't do anything here, but we may want to some day
|
_username = in.readUTF();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected String _username;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
package com.threerings.cocktail.cher.net;
|
||||||
|
|
||||||
@@ -7,7 +7,7 @@ import java.io.IOException;
|
|||||||
import java.io.DataInputStream;
|
import java.io.DataInputStream;
|
||||||
import java.io.DataOutputStream;
|
import java.io.DataOutputStream;
|
||||||
|
|
||||||
import com.threerings.cocktail.cher.dobj.Event;
|
import com.threerings.cocktail.cher.dobj.DEvent;
|
||||||
|
|
||||||
public class EventNotification extends DownstreamMessage
|
public class EventNotification extends DownstreamMessage
|
||||||
{
|
{
|
||||||
@@ -25,7 +25,7 @@ public class EventNotification extends DownstreamMessage
|
|||||||
/**
|
/**
|
||||||
* Constructs an event notification for the supplied event.
|
* Constructs an event notification for the supplied event.
|
||||||
*/
|
*/
|
||||||
public EventNotification (Event event)
|
public EventNotification (DEvent event)
|
||||||
{
|
{
|
||||||
_event = event;
|
_event = event;
|
||||||
}
|
}
|
||||||
@@ -50,5 +50,5 @@ public class EventNotification extends DownstreamMessage
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** The event which we are forwarding. */
|
/** The event which we are forwarding. */
|
||||||
protected Event _event;
|
protected DEvent _event;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
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
|
* Constructs a failure response in response to a request for the
|
||||||
* upstream message id.
|
* specified oid.
|
||||||
*/
|
*/
|
||||||
public FailureResponse (short messageId)
|
public FailureResponse (int oid)
|
||||||
{
|
{
|
||||||
this.messageId = messageId;
|
_oid = oid;
|
||||||
}
|
}
|
||||||
|
|
||||||
public short getType ()
|
public short getType ()
|
||||||
@@ -34,17 +34,24 @@ public class FailureResponse extends DownstreamMessage
|
|||||||
return TYPE;
|
return TYPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getOid ()
|
||||||
|
{
|
||||||
|
return _oid;
|
||||||
|
}
|
||||||
|
|
||||||
public void writeTo (DataOutputStream out)
|
public void writeTo (DataOutputStream out)
|
||||||
throws IOException
|
throws IOException
|
||||||
{
|
{
|
||||||
super.writeTo(out);
|
super.writeTo(out);
|
||||||
out.writeShort(messageId);
|
out.writeInt(_oid);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void readFrom (DataInputStream in)
|
public void readFrom (DataInputStream in)
|
||||||
throws IOException
|
throws IOException
|
||||||
{
|
{
|
||||||
super.readFrom(in);
|
super.readFrom(in);
|
||||||
messageId = in.readShort();
|
_oid = in.readInt();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected int _oid;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
package com.threerings.cocktail.cher.net;
|
||||||
|
|
||||||
@@ -24,12 +24,10 @@ public class ObjectResponse extends DownstreamMessage
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs an object response with supplied distributed object that
|
* Constructs an object response with supplied distributed object.
|
||||||
* is associated with the specified upstream message id.
|
|
||||||
*/
|
*/
|
||||||
public ObjectResponse (short messageId, DObject dobj)
|
public ObjectResponse (DObject dobj)
|
||||||
{
|
{
|
||||||
this.messageId = messageId;
|
|
||||||
_dobj = dobj;
|
_dobj = dobj;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -42,7 +40,6 @@ public class ObjectResponse extends DownstreamMessage
|
|||||||
throws IOException
|
throws IOException
|
||||||
{
|
{
|
||||||
super.writeTo(out);
|
super.writeTo(out);
|
||||||
out.writeShort(messageId);
|
|
||||||
DObjectFactory.writeTo(out, _dobj);
|
DObjectFactory.writeTo(out, _dobj);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -50,7 +47,6 @@ public class ObjectResponse extends DownstreamMessage
|
|||||||
throws IOException
|
throws IOException
|
||||||
{
|
{
|
||||||
super.readFrom(in);
|
super.readFrom(in);
|
||||||
messageId = in.readShort();
|
|
||||||
_dobj = (DObject)DObjectFactory.readFrom(in);
|
_dobj = (DObject)DObjectFactory.readFrom(in);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
package com.threerings.cocktail.cher.net;
|
||||||
|
|
||||||
@@ -24,7 +24,7 @@ public class UsernamePasswordCreds extends Credentials
|
|||||||
*/
|
*/
|
||||||
public UsernamePasswordCreds (String username, String password)
|
public UsernamePasswordCreds (String username, String password)
|
||||||
{
|
{
|
||||||
_username = username;
|
super(username);
|
||||||
_password = password;
|
_password = password;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -33,11 +33,15 @@ public class UsernamePasswordCreds extends Credentials
|
|||||||
return TYPE;
|
return TYPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getPassword ()
|
||||||
|
{
|
||||||
|
return _password;
|
||||||
|
}
|
||||||
|
|
||||||
public void writeTo (DataOutputStream out)
|
public void writeTo (DataOutputStream out)
|
||||||
throws IOException
|
throws IOException
|
||||||
{
|
{
|
||||||
super.writeTo(out);
|
super.writeTo(out);
|
||||||
out.writeUTF(_username);
|
|
||||||
out.writeUTF(_password);
|
out.writeUTF(_password);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -45,10 +49,13 @@ public class UsernamePasswordCreds extends Credentials
|
|||||||
throws IOException
|
throws IOException
|
||||||
{
|
{
|
||||||
super.readFrom(in);
|
super.readFrom(in);
|
||||||
_username = in.readUTF();
|
|
||||||
_password = in.readUTF();
|
_password = in.readUTF();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected String _username;
|
public String toString ()
|
||||||
|
{
|
||||||
|
return "[username=" + _username + ", password=" + _password + "]";
|
||||||
|
}
|
||||||
|
|
||||||
protected String _password;
|
protected String _password;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
package com.threerings.cocktail.cher.server;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
import com.threerings.cocktail.cher.Log;
|
import com.threerings.cocktail.cher.Log;
|
||||||
|
import com.threerings.cocktail.cher.net.Credentials;
|
||||||
import com.threerings.cocktail.cher.server.net.*;
|
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
|
* surprise) which are slightly more than just connections. Clients
|
||||||
* persist in the absence of connections in case a user goes bye bye
|
* persist in the absence of connections in case a user goes bye bye
|
||||||
* unintentionally and wants to reconnect and continue their session.
|
* unintentionally and wants to reconnect and continue their session.
|
||||||
|
*
|
||||||
|
* <p> 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
|
public class ClientManager implements ConnectionObserver
|
||||||
{
|
{
|
||||||
@@ -29,9 +36,22 @@ public class ClientManager implements ConnectionObserver
|
|||||||
*
|
*
|
||||||
* @param conn The newly established connection.
|
* @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 conn The connection in that failed.
|
||||||
* @param fault The exception associated with the failure.
|
* @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);
|
Log.info("Connection failed: " + conn + ": " + fault);
|
||||||
}
|
}
|
||||||
@@ -53,8 +74,10 @@ public class ClientManager implements ConnectionObserver
|
|||||||
*
|
*
|
||||||
* @param conn The recently closed connection.
|
* @param conn The recently closed connection.
|
||||||
*/
|
*/
|
||||||
public void connectionClosed (Connection conn)
|
public synchronized void connectionClosed (Connection conn)
|
||||||
{
|
{
|
||||||
Log.info("Connection closed: " + conn);
|
Log.info("Connection closed: " + conn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected HashMap _clients = new HashMap();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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.
|
||||||
|
*
|
||||||
|
* <p><em>A note on synchronization:</em> the client object is structured
|
||||||
|
* so that its <code>Subscriber</code> 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;
|
||||||
|
}
|
||||||
@@ -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;
|
package com.threerings.cocktail.cher.server;
|
||||||
|
|
||||||
@@ -175,10 +175,11 @@ public class CherDObjectMgr implements DObjectManager
|
|||||||
public boolean applyToObject (DObject target)
|
public boolean applyToObject (DObject target)
|
||||||
throws ObjectAccessException
|
throws ObjectAccessException
|
||||||
{
|
{
|
||||||
|
int oid = getNextOid();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// create a new instance of this object
|
// create a new instance of this object
|
||||||
DObject obj = (DObject)_class.newInstance();
|
DObject obj = (DObject)_class.newInstance();
|
||||||
int oid = getNextOid();
|
|
||||||
|
|
||||||
// initialize this object
|
// initialize this object
|
||||||
obj.init(oid, CherDObjectMgr.this);
|
obj.init(oid, CherDObjectMgr.this);
|
||||||
@@ -205,7 +206,8 @@ public class CherDObjectMgr implements DObjectManager
|
|||||||
// let the subscriber know shit be fucked
|
// let the subscriber know shit be fucked
|
||||||
if (_target != null) {
|
if (_target != null) {
|
||||||
String errmsg = "Object instantiation failed: " + e;
|
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 it don't exist, let them know
|
||||||
if (obj == null) {
|
if (obj == null) {
|
||||||
_target.requestFailed(new NoSuchObjectException(_oid));
|
_target.requestFailed(_oid, new NoSuchObjectException(_oid));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// check permissions
|
// check permissions
|
||||||
if (!obj.checkPermissions(_target)) {
|
if (!obj.checkPermissions(_target)) {
|
||||||
String errmsg = "m.access_denied\t" + _oid;
|
String errmsg = "m.access_denied\t" + _oid;
|
||||||
_target.requestFailed(new ObjectAccessException(errmsg));
|
_target.requestFailed(_oid, new ObjectAccessException(errmsg));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
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
|
* The authing connection manages the client connection until
|
||||||
* authentication has completed (for better or for worse).
|
* 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
|
* Creates a new authing connection object that will manage the
|
||||||
@@ -25,6 +26,8 @@ public class AuthingConnection extends Connection
|
|||||||
throws IOException
|
throws IOException
|
||||||
{
|
{
|
||||||
super(cmgr, socket);
|
super(cmgr, socket);
|
||||||
|
// we are our own message handler
|
||||||
|
setMessageHandler(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -55,6 +58,11 @@ public class AuthingConnection extends Connection
|
|||||||
return _authreq;
|
return _authreq;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String toString ()
|
||||||
|
{
|
||||||
|
return "[mode=AUTHING, addr=" + _socket.getInetAddress() + "]";
|
||||||
|
}
|
||||||
|
|
||||||
protected int _state = AWAITING_AUTH_REQUEST;
|
protected int _state = AWAITING_AUTH_REQUEST;
|
||||||
protected AuthRequest _authreq;
|
protected AuthRequest _authreq;
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
package com.threerings.cocktail.cher.server.net;
|
||||||
|
|
||||||
@@ -45,6 +45,16 @@ public abstract class Connection implements NetEventHandler
|
|||||||
_din = new DataInputStream(_fin);
|
_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.
|
* Returns the select item associated with this connection.
|
||||||
*/
|
*/
|
||||||
@@ -71,6 +81,33 @@ public abstract class Connection implements NetEventHandler
|
|||||||
return _socket;
|
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.
|
* 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
|
// read the available data and see if we have a whole frame
|
||||||
if (_fin.readFrame(_in)) {
|
if (_fin.readFrame(_in)) {
|
||||||
// parse the message and pass it on
|
// parse the message and pass it on
|
||||||
handleMessage((UpstreamMessage)
|
_handler.handleMessage((UpstreamMessage)
|
||||||
TypedObjectFactory.readFrom(_din));
|
TypedObjectFactory.readFrom(_din));
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (EOFException eofe) {
|
} 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
|
* Posts a downstream message for delivery to this connection. The
|
||||||
* message will be delivered by the conmgr thread as soon as it gets
|
* 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 OutputStream _out;
|
||||||
protected FramedInputStream _fin;
|
protected FramedInputStream _fin;
|
||||||
protected DataInputStream _din;
|
protected DataInputStream _din;
|
||||||
|
|
||||||
|
protected MessageHandler _handler;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
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.Log;
|
||||||
import com.threerings.cocktail.cher.io.FramingOutputStream;
|
import com.threerings.cocktail.cher.io.FramingOutputStream;
|
||||||
import com.threerings.cocktail.cher.io.TypedObjectFactory;
|
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.DownstreamMessage;
|
||||||
import com.threerings.cocktail.cher.net.Registry;
|
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
|
* Notifies the connection observers of a connection event. Used
|
||||||
* internally.
|
* internally.
|
||||||
*/
|
*/
|
||||||
protected void notifyObservers (int code, Connection conn,
|
protected void notifyObservers (int code, Connection conn, Object arg)
|
||||||
IOException cause)
|
|
||||||
{
|
{
|
||||||
synchronized (_observers) {
|
synchronized (_observers) {
|
||||||
for (int i = 0; i < _observers.size(); i++) {
|
for (int i = 0; i < _observers.size(); i++) {
|
||||||
@@ -111,10 +111,10 @@ public class ConnectionManager extends LoopingThread
|
|||||||
(ConnectionObserver)_observers.get(i);
|
(ConnectionObserver)_observers.get(i);
|
||||||
switch (code) {
|
switch (code) {
|
||||||
case CONNECTION_ESTABLISHED:
|
case CONNECTION_ESTABLISHED:
|
||||||
obs.connectionEstablished(conn);
|
obs.connectionEstablished(conn, (Credentials)arg);
|
||||||
break;
|
break;
|
||||||
case CONNECTION_FAILED:
|
case CONNECTION_FAILED:
|
||||||
obs.connectionFailed(conn, cause);
|
obs.connectionFailed(conn, (IOException)arg);
|
||||||
break;
|
break;
|
||||||
case CONNECTION_CLOSED:
|
case CONNECTION_CLOSED:
|
||||||
obs.connectionClosed(conn);
|
obs.connectionClosed(conn);
|
||||||
@@ -154,8 +154,8 @@ public class ConnectionManager extends LoopingThread
|
|||||||
}
|
}
|
||||||
|
|
||||||
// check for connections that have completed authentication
|
// check for connections that have completed authentication
|
||||||
Connection conn;
|
AuthingConnection conn;
|
||||||
while ((conn = (Connection)_authq.getNonBlocking()) != null) {
|
while ((conn = (AuthingConnection)_authq.getNonBlocking()) != null) {
|
||||||
// remove the old connection from the select set
|
// remove the old connection from the select set
|
||||||
_selset.remove(conn.getSelectItem());
|
_selset.remove(conn.getSelectItem());
|
||||||
|
|
||||||
@@ -168,7 +168,8 @@ public class ConnectionManager extends LoopingThread
|
|||||||
_selset.add(rconn.getSelectItem());
|
_selset.add(rconn.getSelectItem());
|
||||||
|
|
||||||
// and let our observers know about our new connection
|
// and let our observers know about our new connection
|
||||||
notifyObservers(CONNECTION_ESTABLISHED, rconn, null);
|
notifyObservers(CONNECTION_ESTABLISHED, rconn,
|
||||||
|
conn.getAuthRequest().getCredentials());
|
||||||
|
|
||||||
} catch (IOException ioe) {
|
} catch (IOException ioe) {
|
||||||
Log.warning("Failure upgrading authing connection to " +
|
Log.warning("Failure upgrading authing connection to " +
|
||||||
|
|||||||
@@ -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;
|
package com.threerings.cocktail.cher.server.net;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import com.threerings.cocktail.cher.net.Credentials;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A connection observer can be registered with the connection manager to
|
* A connection observer can be registered with the connection manager to
|
||||||
@@ -23,8 +24,10 @@ public interface ConnectionObserver
|
|||||||
* the connection observer.
|
* the connection observer.
|
||||||
*
|
*
|
||||||
* @param conn The newly established connection.
|
* @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,
|
* Called if a connection fails for any reason. If a connection fails,
|
||||||
|
|||||||
@@ -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);
|
||||||
|
}
|
||||||
@@ -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;
|
package com.threerings.cocktail.cher.server.net;
|
||||||
|
|
||||||
@@ -30,4 +30,9 @@ public class RunningConnection extends Connection
|
|||||||
public void handleMessage (UpstreamMessage msg)
|
public void handleMessage (UpstreamMessage msg)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String toString ()
|
||||||
|
{
|
||||||
|
return "[mode=RUNNING, addr=" + _socket.getInetAddress() + "]";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user