Implemented object destruction; wired up some missing stuff; created a
test server to make some testing easier; various other cleanups. git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@188 542714f4-19e9-0310-aa3c-eee0fc999fb1
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// $Id: ClientDObjectMgr.java,v 1.4 2001/07/19 07:09:16 mdb Exp $
|
// $Id: ClientDObjectMgr.java,v 1.5 2001/08/07 20:38:58 mdb Exp $
|
||||||
|
|
||||||
package com.threerings.cocktail.cher.client;
|
package com.threerings.cocktail.cher.client;
|
||||||
|
|
||||||
@@ -75,6 +75,13 @@ public class ClientDObjectMgr
|
|||||||
_comm.postMessage(new ForwardEventRequest(tevent));
|
_comm.postMessage(new ForwardEventRequest(tevent));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// inherit documentation from the interface
|
||||||
|
public void destroyObject (int oid)
|
||||||
|
{
|
||||||
|
// forward an object destroyed event to the server
|
||||||
|
postEvent(new ObjectDestroyedEvent(oid));
|
||||||
|
}
|
||||||
|
|
||||||
// inherit documentation from the interface
|
// inherit documentation from the interface
|
||||||
public void removedLastSubscriber (DObject obj)
|
public void removedLastSubscriber (DObject obj)
|
||||||
{
|
{
|
||||||
@@ -154,8 +161,29 @@ public class ClientDObjectMgr
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// have the object pass this event on to its subscribers
|
try {
|
||||||
target.notifySubscribers(event);
|
// apply the event to the object
|
||||||
|
boolean notify = event.applyToObject(target);
|
||||||
|
|
||||||
|
// if this is an object destroyed event, we need to remove the
|
||||||
|
// object from our object table
|
||||||
|
if (event instanceof ObjectDestroyedEvent) {
|
||||||
|
Log.info("Uncaching destroyed object " +
|
||||||
|
"[oid=" + target.getOid() + "].");
|
||||||
|
_ocache.remove(target.getOid());
|
||||||
|
}
|
||||||
|
|
||||||
|
// have the object pass this event on to its subscribers if
|
||||||
|
// desired
|
||||||
|
if (notify) {
|
||||||
|
target.notifySubscribers(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.warning("Failure processing event [event=" + event +
|
||||||
|
", target=" + target + "].");
|
||||||
|
Log.logStackTrace(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -193,7 +221,19 @@ public class ClientDObjectMgr
|
|||||||
*/
|
*/
|
||||||
protected void notifyFailure (int oid)
|
protected void notifyFailure (int oid)
|
||||||
{
|
{
|
||||||
Log.info("Get failed: " + oid);
|
// let the penders know that the object is not available
|
||||||
|
PendingRequest req = (PendingRequest)_penders.remove(oid);
|
||||||
|
if (req == null) {
|
||||||
|
Log.warning("Failed to get object, but no one cares?! " +
|
||||||
|
"[oid=" + oid + "].");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < req.targets.size(); i++) {
|
||||||
|
Subscriber target = (Subscriber)req.targets.get(i);
|
||||||
|
// and let them know that the object is in
|
||||||
|
target.requestFailed(oid, null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// $Id: Communicator.java,v 1.12 2001/08/03 02:11:20 mdb Exp $
|
// $Id: Communicator.java,v 1.13 2001/08/07 20:38:58 mdb Exp $
|
||||||
|
|
||||||
package com.threerings.cocktail.cher.client;
|
package com.threerings.cocktail.cher.client;
|
||||||
|
|
||||||
@@ -91,6 +91,9 @@ public class Communicator
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// post a logoff message
|
||||||
|
postMessage(new LogoffRequest());
|
||||||
|
|
||||||
// let our reader and writer know that it's time to go
|
// let our reader and writer know that it's time to go
|
||||||
if (_reader != null) {
|
if (_reader != null) {
|
||||||
// if logoff() is being called by the client as part of a
|
// if logoff() is being called by the client as part of a
|
||||||
@@ -110,28 +113,12 @@ public class Communicator
|
|||||||
if (_writer != null) {
|
if (_writer != null) {
|
||||||
// shutting down the writer thread is simpler because we can
|
// shutting down the writer thread is simpler because we can
|
||||||
// post a termination message on the queue and be sure that it
|
// post a termination message on the queue and be sure that it
|
||||||
// will receive it. we do run the risk that it is in the
|
// will receive it. when the writer thread has delivered our
|
||||||
// middle of trying to send a message when we close the
|
// logoff request and exited, we will complete the logoff
|
||||||
// socket, but in theory the send will fail, it will complain
|
// process by closing our socket and invoking the
|
||||||
// and then it will cleanly exit. if we were uber paranoid
|
// clientDidLogoff callback
|
||||||
// about JVMs misbehaving on simultaneous close()/write(), we
|
|
||||||
// could wait here for the writer thread to exit, but that
|
|
||||||
// makes me even more nervous because I know that some JVMs
|
|
||||||
// don't handle Thread.join() properly (hopefully no one is
|
|
||||||
// still using those JVMs but one can never be sure)
|
|
||||||
_writer.shutdown();
|
_writer.shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
// close down our socket
|
|
||||||
try {
|
|
||||||
_socket.close();
|
|
||||||
} catch (IOException cle) {
|
|
||||||
Log.warning("Error closing failed socket: " + cle);
|
|
||||||
}
|
|
||||||
_socket = null;
|
|
||||||
|
|
||||||
// let the client observers know that we're logged off
|
|
||||||
_client.notifyObservers(Client.CLIENT_DID_LOGOFF, null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -226,8 +213,20 @@ public class Communicator
|
|||||||
{
|
{
|
||||||
// clear out our writer reference
|
// clear out our writer reference
|
||||||
_writer = null;
|
_writer = null;
|
||||||
|
|
||||||
Log.info("Writer thread exited.");
|
Log.info("Writer thread exited.");
|
||||||
|
|
||||||
|
// now that the writer thread has gone away, we can safely close
|
||||||
|
// our socket and let the client know that the logoff process has
|
||||||
|
// completed
|
||||||
|
try {
|
||||||
|
_socket.close();
|
||||||
|
} catch (IOException cle) {
|
||||||
|
Log.warning("Error closing failed socket: " + cle);
|
||||||
|
}
|
||||||
|
_socket = null;
|
||||||
|
|
||||||
|
// let the client observers know that we're logged off
|
||||||
|
_client.notifyObservers(Client.CLIENT_DID_LOGOFF, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// $Id: DObject.java,v 1.19 2001/08/04 00:39:44 mdb Exp $
|
// $Id: DObject.java,v 1.20 2001/08/07 20:38:58 mdb Exp $
|
||||||
|
|
||||||
package com.threerings.cocktail.cher.dobj;
|
package com.threerings.cocktail.cher.dobj;
|
||||||
|
|
||||||
@@ -233,6 +233,16 @@ public class DObject
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Requests that this distributed object be destroyed. It does so by
|
||||||
|
* queueing up an object destroyed event which the server will
|
||||||
|
* validate and process.
|
||||||
|
*/
|
||||||
|
public void destroy ()
|
||||||
|
{
|
||||||
|
_mgr.postEvent(new ObjectDestroyedEvent(_oid));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks to ensure that the specified subscriber has access to this
|
* Checks to ensure that the specified subscriber has access to this
|
||||||
* object. This will be called before satisfying a subscription
|
* object. This will be called before satisfying a subscription
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// $Id: DObjectManager.java,v 1.7 2001/08/02 04:49:08 mdb Exp $
|
// $Id: DObjectManager.java,v 1.8 2001/08/07 20:38:58 mdb Exp $
|
||||||
|
|
||||||
package com.threerings.cocktail.cher.dobj;
|
package com.threerings.cocktail.cher.dobj;
|
||||||
|
|
||||||
@@ -59,6 +59,15 @@ public interface DObjectManager
|
|||||||
*/
|
*/
|
||||||
public void unsubscribeFromObject (int oid, Subscriber target);
|
public void unsubscribeFromObject (int oid, Subscriber target);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Requests that the specified object be destroyed. Once destroyed an
|
||||||
|
* object is removed from the runtime system and may no longer have
|
||||||
|
* events dispatched on it.
|
||||||
|
*
|
||||||
|
* @param oid The object id of the distributed object to be destroyed.
|
||||||
|
*/
|
||||||
|
public void destroyObject (int oid);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Posts a distributed object event into the system. Instead of
|
* Posts a distributed object event into the system. Instead of
|
||||||
* requesting the modification of a distributed object attribute by
|
* requesting the modification of a distributed object attribute by
|
||||||
|
|||||||
@@ -0,0 +1,63 @@
|
|||||||
|
//
|
||||||
|
// $Id: ObjectDestroyedEvent.java,v 1.1 2001/08/07 20:38:58 mdb Exp $
|
||||||
|
|
||||||
|
package com.threerings.cocktail.cher.dobj;
|
||||||
|
|
||||||
|
import java.io.DataInputStream;
|
||||||
|
import java.io.DataOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An object destroyed event is dispatched when an object has been removed
|
||||||
|
* from the distributed object system. It can also be constructed to
|
||||||
|
* request an attribute change on an object and posted to the dobjmgr.
|
||||||
|
*
|
||||||
|
* @see DObjectManager#postEvent
|
||||||
|
*/
|
||||||
|
public class ObjectDestroyedEvent extends TypedEvent
|
||||||
|
{
|
||||||
|
/** The typed object code for this event. */
|
||||||
|
public static final short TYPE = TYPE_BASE + 7;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new object destroyed event for the specified
|
||||||
|
* distributed object.
|
||||||
|
*
|
||||||
|
* @param targetOid the object id of the object that will be destroyed.
|
||||||
|
*/
|
||||||
|
public ObjectDestroyedEvent (int targetOid)
|
||||||
|
{
|
||||||
|
super(targetOid);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a blank instance of this event in preparation for
|
||||||
|
* unserialization from the network.
|
||||||
|
*/
|
||||||
|
public ObjectDestroyedEvent ()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Applies this attribute change to the object.
|
||||||
|
*/
|
||||||
|
public boolean applyToObject (DObject target)
|
||||||
|
throws ObjectAccessException
|
||||||
|
{
|
||||||
|
// nothing to do in preparation for destruction, the omgr will
|
||||||
|
// have to recognize this type of event and do the right thing
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public short getType ()
|
||||||
|
{
|
||||||
|
return TYPE;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void toString (StringBuffer buf)
|
||||||
|
{
|
||||||
|
buf.append("DESTROY:");
|
||||||
|
super.toString(buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// $Id: DObjectFactory.java,v 1.6 2001/08/03 02:11:40 mdb Exp $
|
// $Id: DObjectFactory.java,v 1.7 2001/08/07 20:38:58 mdb Exp $
|
||||||
|
|
||||||
package com.threerings.cocktail.cher.dobj.io;
|
package com.threerings.cocktail.cher.dobj.io;
|
||||||
|
|
||||||
@@ -49,7 +49,7 @@ public class DObjectFactory
|
|||||||
Class clazz = Class.forName(in.readUTF());
|
Class clazz = Class.forName(in.readUTF());
|
||||||
DObject dobj = (DObject)clazz.newInstance();
|
DObject dobj = (DObject)clazz.newInstance();
|
||||||
dobj.setOid(in.readInt()); // read and set the oid
|
dobj.setOid(in.readInt()); // read and set the oid
|
||||||
Log.info("Unmarshalling object: " + dobj);
|
// Log.info("Unmarshalling object: " + dobj);
|
||||||
|
|
||||||
// look up the marshaller for that class
|
// look up the marshaller for that class
|
||||||
Marshaller marsh = getMarshaller(clazz);
|
Marshaller marsh = getMarshaller(clazz);
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// $Id: TypedObjectRegistry.java,v 1.4 2001/08/04 01:05:25 mdb Exp $
|
// $Id: TypedObjectRegistry.java,v 1.5 2001/08/07 20:38:58 mdb Exp $
|
||||||
|
|
||||||
package com.threerings.cocktail.cher.io;
|
package com.threerings.cocktail.cher.io;
|
||||||
|
|
||||||
@@ -64,5 +64,7 @@ public class TypedObjectRegistry
|
|||||||
ObjectRemovedEvent.class);
|
ObjectRemovedEvent.class);
|
||||||
TypedObjectFactory.registerClass(ReleaseLockEvent.TYPE,
|
TypedObjectFactory.registerClass(ReleaseLockEvent.TYPE,
|
||||||
ReleaseLockEvent.class);
|
ReleaseLockEvent.class);
|
||||||
|
TypedObjectFactory.registerClass(ObjectDestroyedEvent.TYPE,
|
||||||
|
ObjectDestroyedEvent.class);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,11 @@
|
|||||||
//
|
//
|
||||||
// $Id: PresentsDObjectMgr.java,v 1.9 2001/07/23 21:12:55 mdb Exp $
|
// $Id: PresentsDObjectMgr.java,v 1.10 2001/08/07 20:38:58 mdb Exp $
|
||||||
|
|
||||||
package com.threerings.cocktail.cher.server;
|
package com.threerings.cocktail.cher.server;
|
||||||
|
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
import com.samskivert.util.Queue;
|
import com.samskivert.util.Queue;
|
||||||
|
|
||||||
import com.threerings.cocktail.cher.Log;
|
import com.threerings.cocktail.cher.Log;
|
||||||
@@ -61,6 +64,13 @@ public class CherDObjectMgr implements DObjectManager
|
|||||||
AccessObjectEvent.UNSUBSCRIBE));
|
AccessObjectEvent.UNSUBSCRIBE));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// inherit documentation from the interface
|
||||||
|
public void destroyObject (int oid)
|
||||||
|
{
|
||||||
|
// queue up an object destroyed event
|
||||||
|
postEvent(new ObjectDestroyedEvent(oid));
|
||||||
|
}
|
||||||
|
|
||||||
// inherit documentation from the interface
|
// inherit documentation from the interface
|
||||||
public void postEvent (DEvent event)
|
public void postEvent (DEvent event)
|
||||||
{
|
{
|
||||||
@@ -121,7 +131,10 @@ public class CherDObjectMgr implements DObjectManager
|
|||||||
|
|
||||||
// do any internal management necessary based on this
|
// do any internal management necessary based on this
|
||||||
// event
|
// event
|
||||||
// **TBD**
|
Method helper = (Method)_helpers.get(event.getClass());
|
||||||
|
if (helper != null) {
|
||||||
|
helper.invoke(this, new Object[] { event, target });
|
||||||
|
}
|
||||||
|
|
||||||
// if the event returns false from applyToObject, this
|
// if the event returns false from applyToObject, this
|
||||||
// means it's a silent event and we shouldn't notify the
|
// means it's a silent event and we shouldn't notify the
|
||||||
@@ -153,6 +166,17 @@ public class CherDObjectMgr implements DObjectManager
|
|||||||
_evqueue.append(new ShutdownEvent());
|
_evqueue.append(new ShutdownEvent());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called as a helper for <code>ObjectDestroyedEvent</code> events. It
|
||||||
|
* removes the object from the object table.
|
||||||
|
*/
|
||||||
|
public void objectDestroyed (DEvent event, DObject target)
|
||||||
|
{
|
||||||
|
Log.info("Removing destroyed object from table " +
|
||||||
|
"[oid=" + target.getOid() + "].");
|
||||||
|
_objects.remove(target.getOid());
|
||||||
|
}
|
||||||
|
|
||||||
protected synchronized boolean isRunning ()
|
protected synchronized boolean isRunning ()
|
||||||
{
|
{
|
||||||
return _running;
|
return _running;
|
||||||
@@ -170,11 +194,6 @@ public class CherDObjectMgr implements DObjectManager
|
|||||||
return _nextOid;
|
return _nextOid;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean _running = true;
|
|
||||||
protected Queue _evqueue = new Queue();
|
|
||||||
protected IntMap _objects = new IntMap();
|
|
||||||
protected int _nextOid = 0;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used to create a distributed object and register it with the
|
* Used to create a distributed object and register it with the
|
||||||
* system.
|
* system.
|
||||||
@@ -318,4 +337,35 @@ public class CherDObjectMgr implements DObjectManager
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers our event helper methods.
|
||||||
|
*/
|
||||||
|
protected static void registerEventHelpers ()
|
||||||
|
{
|
||||||
|
Class[] ptypes = new Class[] { DEvent.class, DObject.class };
|
||||||
|
Class omgrcl = CherDObjectMgr.class;
|
||||||
|
Method method;
|
||||||
|
|
||||||
|
try {
|
||||||
|
method = omgrcl.getMethod("objectDestroyed", ptypes);
|
||||||
|
_helpers.put(ObjectDestroyedEvent.class, method);
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.warning("Unable to register event helpers " +
|
||||||
|
"[error=" + e + "].");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean _running = true;
|
||||||
|
protected Queue _evqueue = new Queue();
|
||||||
|
protected IntMap _objects = new IntMap();
|
||||||
|
protected int _nextOid = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This table maps event classes to helper methods that perform some
|
||||||
|
* additional processing for particular events.
|
||||||
|
*/
|
||||||
|
protected static HashMap _helpers = new HashMap();
|
||||||
|
static { registerEventHelpers(); }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// $Id: ConnectionManager.java,v 1.7 2001/08/03 02:12:52 mdb Exp $
|
// $Id: ConnectionManager.java,v 1.8 2001/08/07 20:38:58 mdb Exp $
|
||||||
|
|
||||||
package com.threerings.cocktail.cher.server.net;
|
package com.threerings.cocktail.cher.server.net;
|
||||||
|
|
||||||
@@ -216,7 +216,7 @@ public class ConnectionManager extends LoopingThread
|
|||||||
if (socket == null) {
|
if (socket == null) {
|
||||||
// in theory this shouldn't happen because we got an
|
// in theory this shouldn't happen because we got an
|
||||||
// ACCEPT_READY event, but better safe than sorry
|
// ACCEPT_READY event, but better safe than sorry
|
||||||
Log.info("Psych! Got ACCEPT_READY, but no connection.");
|
// Log.info("Psych! Got ACCEPT_READY, but no connection.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// $Id: RunningConnection.java,v 1.3 2001/06/02 01:30:37 mdb Exp $
|
// $Id: RunningConnection.java,v 1.4 2001/08/07 20:38:58 mdb Exp $
|
||||||
|
|
||||||
package com.threerings.cocktail.cher.server.net;
|
package com.threerings.cocktail.cher.server.net;
|
||||||
|
|
||||||
@@ -33,6 +33,10 @@ public class RunningConnection extends Connection
|
|||||||
|
|
||||||
public String toString ()
|
public String toString ()
|
||||||
{
|
{
|
||||||
return "[mode=RUNNING, addr=" + _socket.getInetAddress() + "]";
|
if (_socket != null) {
|
||||||
|
return "[mode=RUNNING, addr=" + _socket.getInetAddress() + "]";
|
||||||
|
} else {
|
||||||
|
return "[mode=RUNNING, addr=<disconnected>]";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
#
|
||||||
|
# $Id: server.properties,v 1.1 2001/08/07 20:38:58 mdb Exp $
|
||||||
|
#
|
||||||
|
# Configuration for the Cher test server
|
||||||
|
|
||||||
|
# These invocation service providers will be registered with the
|
||||||
|
# invocation manager during the server init process
|
||||||
|
providers = \
|
||||||
|
test = com.threerings.cocktail.cher.server.test.TestProvider
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// $Id: TestClient.java,v 1.7 2001/07/19 19:18:06 mdb Exp $
|
// $Id: TestClient.java,v 1.8 2001/08/07 20:38:58 mdb Exp $
|
||||||
|
|
||||||
package com.threerings.cocktail.cher.client.test;
|
package com.threerings.cocktail.cher.client.test;
|
||||||
|
|
||||||
@@ -18,6 +18,11 @@ import com.threerings.cocktail.cher.server.test.TestObject;
|
|||||||
public class TestClient
|
public class TestClient
|
||||||
implements Client.Invoker, ClientObserver, Subscriber
|
implements Client.Invoker, ClientObserver, Subscriber
|
||||||
{
|
{
|
||||||
|
public void setClient (Client client)
|
||||||
|
{
|
||||||
|
_client = client;
|
||||||
|
}
|
||||||
|
|
||||||
public void invokeLater (Runnable run)
|
public void invokeLater (Runnable run)
|
||||||
{
|
{
|
||||||
// queue it on up
|
// queue it on up
|
||||||
@@ -36,13 +41,11 @@ public class TestClient
|
|||||||
public void clientDidLogon (Client client)
|
public void clientDidLogon (Client client)
|
||||||
{
|
{
|
||||||
Log.info("Client did logon [client=" + client + "].");
|
Log.info("Client did logon [client=" + client + "].");
|
||||||
// try subscribing to a test object
|
|
||||||
client.getDObjectManager().subscribeToObject(2, this);
|
|
||||||
// register our test notification receiver
|
// register our test notification receiver
|
||||||
client.getInvocationManager().registerReceiver(TestService.MODULE,
|
client.getInvocationManager().registerReceiver(TestService.MODULE,
|
||||||
new TestReceiver());
|
new TestReceiver());
|
||||||
// issue a test invocation request
|
// get the test object id
|
||||||
TestService.test(client, "foo", 1, this);
|
TestService.getTestOid(client, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void clientFailedToLogon (Client client, Exception cause)
|
public void clientFailedToLogon (Client client, Exception cause)
|
||||||
@@ -79,28 +82,41 @@ public class TestClient
|
|||||||
{
|
{
|
||||||
Log.info("Object unavailable [oid=" + oid +
|
Log.info("Object unavailable [oid=" + oid +
|
||||||
", reason=" + cause + "].");
|
", reason=" + cause + "].");
|
||||||
|
// nothing to do, so might as well logoff
|
||||||
|
_client.logoff(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean handleEvent (DEvent event, DObject target)
|
public boolean handleEvent (DEvent event, DObject target)
|
||||||
{
|
{
|
||||||
Log.info("Got event [event=" + event + ", target=" + target + "].");
|
Log.info("Got event [event=" + event + ", target=" + target + "].");
|
||||||
// dispatch a second event
|
if (event instanceof AttributeChangedEvent) {
|
||||||
((TestObject)target).setBar("rofl!");
|
// request to destroy the object
|
||||||
// unsubscribe to the object to make sure we don't get the event
|
target.destroy();
|
||||||
return false;
|
} else {
|
||||||
|
// request that we log off
|
||||||
|
_client.logoff(true);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void handleTestSucceeded (String one, int two)
|
public void handleTestSucceeded (int invid, String one, int two)
|
||||||
{
|
{
|
||||||
Log.info("Got test response [one=" + one + ", two=" + two + "].");
|
Log.info("Got test response [one=" + one + ", two=" + two + "].");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void handleGotTestOid (int invid, int oid)
|
||||||
|
{
|
||||||
|
// subscribe to the test object
|
||||||
|
_client.getDObjectManager().subscribeToObject(oid, this);
|
||||||
|
}
|
||||||
|
|
||||||
public static void main (String[] args)
|
public static void main (String[] args)
|
||||||
{
|
{
|
||||||
TestClient tclient = new TestClient();
|
TestClient tclient = new TestClient();
|
||||||
UsernamePasswordCreds creds =
|
UsernamePasswordCreds creds =
|
||||||
new UsernamePasswordCreds("test", "test");
|
new UsernamePasswordCreds("test", "test");
|
||||||
Client client = new Client(creds, tclient);
|
Client client = new Client(creds, tclient);
|
||||||
|
tclient.setClient(client);
|
||||||
client.addObserver(tclient);
|
client.addObserver(tclient);
|
||||||
client.setServer("localhost", 4007);
|
client.setServer("localhost", 4007);
|
||||||
client.logon();
|
client.logon();
|
||||||
@@ -109,4 +125,5 @@ public class TestClient
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected Queue _queue = new Queue();
|
protected Queue _queue = new Queue();
|
||||||
|
protected Client _client;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// $Id: TestService.java,v 1.1 2001/07/19 07:48:25 mdb Exp $
|
// $Id: TestService.java,v 1.2 2001/08/07 20:38:58 mdb Exp $
|
||||||
|
|
||||||
package com.threerings.cocktail.cher.client.test;
|
package com.threerings.cocktail.cher.client.test;
|
||||||
|
|
||||||
@@ -22,4 +22,11 @@ public class TestService
|
|||||||
invmgr.invoke(MODULE, "Test", args, rsptarget);
|
invmgr.invoke(MODULE, "Test", args, rsptarget);
|
||||||
Log.info("Sent test request [one=" + one + ", two=" + two + "].");
|
Log.info("Sent test request [one=" + one + ", two=" + two + "].");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void getTestOid (Client client, Object rsptarget)
|
||||||
|
{
|
||||||
|
InvocationManager invmgr = client.getInvocationManager();
|
||||||
|
Object[] args = new Object[0];
|
||||||
|
invmgr.invoke(MODULE, "GetTestOid", args, rsptarget);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// $Id: TestProvider.java,v 1.4 2001/07/19 19:18:07 mdb Exp $
|
// $Id: TestProvider.java,v 1.5 2001/08/07 20:38:58 mdb Exp $
|
||||||
|
|
||||||
package com.threerings.cocktail.cher.server.test;
|
package com.threerings.cocktail.cher.server.test;
|
||||||
|
|
||||||
@@ -27,4 +27,10 @@ public class TestProvider extends InvocationProvider
|
|||||||
// and issue a response to this invocation request
|
// and issue a response to this invocation request
|
||||||
return createResponse("TestSucceeded", one, new Integer(two));
|
return createResponse("TestSucceeded", one, new Integer(two));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Object[] handleGetTestOidRequest (ClientObject source)
|
||||||
|
{
|
||||||
|
int oid = TestServer.testobj.getOid();
|
||||||
|
return createResponse("GotTestOid", new Integer(oid));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,70 @@
|
|||||||
|
//
|
||||||
|
// $Id: TestServer.java,v 1.1 2001/08/07 20:38:58 mdb Exp $
|
||||||
|
|
||||||
|
package com.threerings.cocktail.cher.server.test;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import com.threerings.cocktail.cher.Log;
|
||||||
|
import com.threerings.cocktail.cher.dobj.*;
|
||||||
|
import com.threerings.cocktail.cher.server.*;
|
||||||
|
|
||||||
|
public class TestServer extends CherServer
|
||||||
|
{
|
||||||
|
/** The namespace used for server config properties. */
|
||||||
|
public static final String CONFIG_KEY = "test";
|
||||||
|
|
||||||
|
public static TestObject testobj;
|
||||||
|
|
||||||
|
public void init ()
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
|
super.init();
|
||||||
|
|
||||||
|
// bind the party server config into the namespace
|
||||||
|
config.bindProperties(CONFIG_KEY, CONFIG_PATH);
|
||||||
|
|
||||||
|
// register our invocation service providers
|
||||||
|
registerProviders(config.getValue(PROVIDERS_KEY, (String[])null));
|
||||||
|
|
||||||
|
// create a test object
|
||||||
|
Subscriber sub = new Subscriber()
|
||||||
|
{
|
||||||
|
public void objectAvailable (DObject object)
|
||||||
|
{
|
||||||
|
testobj = (TestObject)object;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void requestFailed (int oid, ObjectAccessException cause)
|
||||||
|
{
|
||||||
|
Log.warning("Unable to create test object " +
|
||||||
|
"[error=" + cause + "].");
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean handleEvent (DEvent event, DObject target)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
omgr.createObject(TestObject.class, sub, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main (String[] args)
|
||||||
|
{
|
||||||
|
TestServer server = new TestServer();
|
||||||
|
try {
|
||||||
|
server.init();
|
||||||
|
server.run();
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.warning("Unable to initialize server.");
|
||||||
|
Log.logStackTrace(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// the path to the config file
|
||||||
|
protected final static String CONFIG_PATH =
|
||||||
|
"rsrc/config/cocktail/cher/test/server";
|
||||||
|
|
||||||
|
// the config key for our list of invocation provider mappings
|
||||||
|
protected final static String PROVIDERS_KEY = CONFIG_KEY + ".providers";
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user