diff --git a/src/java/com/threerings/presents/client/ClientDObjectMgr.java b/src/java/com/threerings/presents/client/ClientDObjectMgr.java index d36fbe804..7d76da037 100644 --- a/src/java/com/threerings/presents/client/ClientDObjectMgr.java +++ b/src/java/com/threerings/presents/client/ClientDObjectMgr.java @@ -1,5 +1,5 @@ // -// $Id: ClientDObjectMgr.java,v 1.18 2002/12/04 22:04:46 shaper Exp $ +// $Id: ClientDObjectMgr.java,v 1.19 2003/01/21 22:02:37 mdb Exp $ package com.threerings.presents.client; @@ -91,11 +91,8 @@ public class ClientDObjectMgr // inherit documentation from the interface public void removedLastSubscriber (DObject obj) { - // if object has no subscribers, we no longer need to proxy it; - // first remove it from the object table - _ocache.remove(obj.getOid()); - - // then ship off an unsubscribe message to the server + // ship off an unsubscribe message to the server; we'll remove the + // object from our table when we get the unsub ack _comm.postMessage(new UnsubscribeRequest(obj.getOid())); } @@ -133,6 +130,17 @@ public class ClientDObjectMgr } else if (obj instanceof ObjectResponse) { registerObjectAndNotify(((ObjectResponse)obj).getObject()); + } else if (obj instanceof UnsubscribeResponse) { + // now that the server has removed our subscription, we + // can remove the object from our local table because we + // should not receive further events for this object; it's + // possible that the object was destroyed (and thus + // removed from our table) in between our request to + // unsubscribe and the unsub response from the server, + // otherwise we'd log a warning if we failed to remove the + // object from our local table here + _ocache.remove(((UnsubscribeResponse)obj).getOid()); + } else if (obj instanceof FailureResponse) { int oid = ((FailureResponse)obj).getOid(); notifyFailure(oid); diff --git a/src/java/com/threerings/presents/net/UnsubscribeResponse.java b/src/java/com/threerings/presents/net/UnsubscribeResponse.java new file mode 100644 index 000000000..103acf382 --- /dev/null +++ b/src/java/com/threerings/presents/net/UnsubscribeResponse.java @@ -0,0 +1,40 @@ +// +// $Id: UnsubscribeResponse.java,v 1.1 2003/01/21 22:02:37 mdb Exp $ + +package com.threerings.presents.net; + +/** + * Used to communicate to the client that we received their unsubscribe + * request and that it is now OK to remove an object mapping from their + * local object table. + */ +public class UnsubscribeResponse extends DownstreamMessage +{ + /** + * Zero argument constructor used when unserializing an instance. + */ + public UnsubscribeResponse () + { + super(); + } + + /** + * Constructs an unsubscribe response with the supplied oid. + */ + public UnsubscribeResponse (int oid) + { + _oid = oid; + } + + public int getOid () + { + return _oid; + } + + public String toString () + { + return "[type=UNACK, msgid=" + messageId + ", oid=" + _oid + "]"; + } + + protected int _oid; +} diff --git a/src/java/com/threerings/presents/server/PresentsClient.java b/src/java/com/threerings/presents/server/PresentsClient.java index 296a39304..abb3cad11 100644 --- a/src/java/com/threerings/presents/server/PresentsClient.java +++ b/src/java/com/threerings/presents/server/PresentsClient.java @@ -1,5 +1,5 @@ // -// $Id: PresentsClient.java,v 1.49 2002/12/22 19:16:31 mdb Exp $ +// $Id: PresentsClient.java,v 1.50 2003/01/21 22:02:37 mdb Exp $ package com.threerings.presents.server; @@ -34,6 +34,7 @@ import com.threerings.presents.net.UnsubscribeRequest; import com.threerings.presents.net.FailureResponse; import com.threerings.presents.net.ObjectResponse; import com.threerings.presents.net.PongResponse; +import com.threerings.presents.net.UnsubscribeResponse; import com.threerings.presents.server.net.Connection; import com.threerings.presents.server.net.MessageHandler; @@ -728,13 +729,22 @@ public class PresentsClient public void dispatch (PresentsClient client, UpstreamMessage msg) { UnsubscribeRequest req = (UnsubscribeRequest)msg; -// Log.info("Unsubscribing [client=" + client + -// ", oid=" + req.getOid() + "]."); + int oid = req.getOid(); +// Log.info("Unsubscribing " + client + " [oid=" + oid + "]."); // forward the unsubscribe request to the omgr for processing - PresentsServer.omgr.unsubscribeFromObject(req.getOid(), client); + PresentsServer.omgr.unsubscribeFromObject(oid, client); // update our subscription tracking table - client.unmapSubscrip(req.getOid()); + client.unmapSubscrip(oid); + + // post a response to the client letting them know that we + // will no longer send them events regarding this object + Connection conn = client.getConnection(); + if (conn != null) { + conn.postMessage(new UnsubscribeResponse(oid)); + } else { + Log.info("Dropped unsub ack " + client + " [oid=" + oid + "]."); + } } }