crowdPeerService field. */
+ public static final String CROWD_PEER_SERVICE = "crowdPeerService";
+ // AUTO-GENERATED: FIELDS END
+
+ /** Used to coordinate tells between servers. */
+ public CrowdPeerMarshaller crowdPeerService;
+
+ // AUTO-GENERATED: METHODS START
+ /**
+ * Requests that the crowdPeerService field be set to the
+ * specified value. The local value will be updated immediately and an
+ * event will be propagated through the system to notify all listeners
+ * that the attribute did change. Proxied copies of this object (on
+ * clients) will apply the value change when they received the
+ * attribute changed notification.
+ */
+ public void setCrowdPeerService (CrowdPeerMarshaller value)
+ {
+ CrowdPeerMarshaller ovalue = this.crowdPeerService;
+ requestAttributeChange(
+ CROWD_PEER_SERVICE, value, ovalue);
+ this.crowdPeerService = value;
+ }
+ // AUTO-GENERATED: METHODS END
+}
diff --git a/src/java/com/threerings/crowd/peer/data/CrowdPeerMarshaller.java b/src/java/com/threerings/crowd/peer/data/CrowdPeerMarshaller.java
new file mode 100644
index 000000000..d670ef6b2
--- /dev/null
+++ b/src/java/com/threerings/crowd/peer/data/CrowdPeerMarshaller.java
@@ -0,0 +1,55 @@
+//
+// $Id$
+//
+// Narya library - tools for developing networked games
+// Copyright (C) 2002-2006 Three Rings Design, Inc., All Rights Reserved
+// http://www.threerings.net/code/narya/
+//
+// This library is free software; you can redistribute it and/or modify it
+// under the terms of the GNU Lesser General Public License as published
+// by the Free Software Foundation; either version 2.1 of the License, or
+// (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+package com.threerings.crowd.peer.data;
+
+import com.threerings.crowd.chat.client.ChatService;
+import com.threerings.crowd.chat.data.ChatMarshaller;
+import com.threerings.crowd.chat.data.ChatMessage;
+import com.threerings.crowd.peer.client.CrowdPeerService;
+import com.threerings.presents.client.Client;
+import com.threerings.presents.data.InvocationMarshaller;
+import com.threerings.presents.dobj.InvocationResponseEvent;
+
+/**
+ * Provides the implementation of the {@link CrowdPeerService} interface
+ * that marshalls the arguments and delivers the request to the provider
+ * on the server. Also provides an implementation of the response listener
+ * interfaces that marshall the response arguments and deliver them back
+ * to the requesting client.
+ */
+public class CrowdPeerMarshaller extends InvocationMarshaller
+ implements CrowdPeerService
+{
+ /** The method id used to dispatch {@link #deliverTell} requests. */
+ public static final int DELIVER_TELL = 1;
+
+ // documentation inherited from interface
+ public void deliverTell (Client arg1, ChatMessage arg2, ChatService.TellListener arg3)
+ {
+ ChatMarshaller.TellMarshaller listener3 = new ChatMarshaller.TellMarshaller();
+ listener3.listener = arg3;
+ sendRequest(arg1, DELIVER_TELL, new Object[] {
+ arg2, listener3
+ });
+ }
+
+}
diff --git a/src/java/com/threerings/crowd/peer/server/CrowdPeerDispatcher.java b/src/java/com/threerings/crowd/peer/server/CrowdPeerDispatcher.java
new file mode 100644
index 000000000..e4d4b9feb
--- /dev/null
+++ b/src/java/com/threerings/crowd/peer/server/CrowdPeerDispatcher.java
@@ -0,0 +1,73 @@
+//
+// $Id$
+//
+// Narya library - tools for developing networked games
+// Copyright (C) 2002-2006 Three Rings Design, Inc., All Rights Reserved
+// http://www.threerings.net/code/narya/
+//
+// This library is free software; you can redistribute it and/or modify it
+// under the terms of the GNU Lesser General Public License as published
+// by the Free Software Foundation; either version 2.1 of the License, or
+// (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+package com.threerings.crowd.peer.server;
+
+import com.threerings.crowd.chat.client.ChatService;
+import com.threerings.crowd.chat.data.ChatMarshaller;
+import com.threerings.crowd.chat.data.ChatMessage;
+import com.threerings.crowd.peer.client.CrowdPeerService;
+import com.threerings.crowd.peer.data.CrowdPeerMarshaller;
+import com.threerings.presents.client.Client;
+import com.threerings.presents.data.ClientObject;
+import com.threerings.presents.data.InvocationMarshaller;
+import com.threerings.presents.server.InvocationDispatcher;
+import com.threerings.presents.server.InvocationException;
+
+/**
+ * Dispatches requests to the {@link CrowdPeerProvider}.
+ */
+public class CrowdPeerDispatcher extends InvocationDispatcher
+{
+ /**
+ * Creates a dispatcher that may be registered to dispatch invocation
+ * service requests for the specified provider.
+ */
+ public CrowdPeerDispatcher (CrowdPeerProvider provider)
+ {
+ this.provider = provider;
+ }
+
+ // documentation inherited
+ public InvocationMarshaller createMarshaller ()
+ {
+ return new CrowdPeerMarshaller();
+ }
+
+ // documentation inherited
+ public void dispatchRequest (
+ ClientObject source, int methodId, Object[] args)
+ throws InvocationException
+ {
+ switch (methodId) {
+ case CrowdPeerMarshaller.DELIVER_TELL:
+ ((CrowdPeerProvider)provider).deliverTell(
+ source,
+ (ChatMessage)args[0], (ChatService.TellListener)args[1]
+ );
+ return;
+
+ default:
+ super.dispatchRequest(source, methodId, args);
+ return;
+ }
+ }
+}
diff --git a/src/java/com/threerings/crowd/peer/server/CrowdPeerManager.java b/src/java/com/threerings/crowd/peer/server/CrowdPeerManager.java
new file mode 100644
index 000000000..b703fd91d
--- /dev/null
+++ b/src/java/com/threerings/crowd/peer/server/CrowdPeerManager.java
@@ -0,0 +1,53 @@
+//
+// $Id$
+//
+// Narya library - tools for developing networked games
+// Copyright (C) 2002-2006 Three Rings Design, Inc., All Rights Reserved
+// http://www.threerings.net/code/narya/
+//
+// This library is free software; you can redistribute it and/or modify it
+// under the terms of the GNU Lesser General Public License as published
+// by the Free Software Foundation; either version 2.1 of the License, or
+// (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+package com.threerings.crowd.peer.server;
+
+import com.samskivert.io.PersistenceException;
+import com.samskivert.jdbc.ConnectionProvider;
+import com.samskivert.util.Invoker;
+
+import com.threerings.presents.peer.data.NodeObject;
+import com.threerings.presents.peer.server.PeerManager;
+
+import com.threerings.crowd.peer.data.CrowdNodeObject;
+
+/**
+ * Extends the standard peer manager and bridges certain Crowd services.
+ */
+public class CrowdPeerManager extends PeerManager
+{
+ /**
+ * Creates a peer manager that integrates Crowd services across a cluster
+ * of servers.
+ */
+ public CrowdPeerManager (ConnectionProvider conprov, Invoker invoker)
+ throws PersistenceException
+ {
+ super(conprov, invoker);
+ }
+
+ @Override // documentation inherited
+ protected Class extends NodeObject> getNodeObjectClass ()
+ {
+ return CrowdNodeObject.class;
+ }
+}
diff --git a/src/java/com/threerings/crowd/peer/server/CrowdPeerProvider.java b/src/java/com/threerings/crowd/peer/server/CrowdPeerProvider.java
new file mode 100644
index 000000000..a289067c4
--- /dev/null
+++ b/src/java/com/threerings/crowd/peer/server/CrowdPeerProvider.java
@@ -0,0 +1,43 @@
+//
+// $Id$
+//
+// Narya library - tools for developing networked games
+// Copyright (C) 2002-2006 Three Rings Design, Inc., All Rights Reserved
+// http://www.threerings.net/code/narya/
+//
+// This library is free software; you can redistribute it and/or modify it
+// under the terms of the GNU Lesser General Public License as published
+// by the Free Software Foundation; either version 2.1 of the License, or
+// (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+package com.threerings.crowd.peer.server;
+
+import com.threerings.crowd.chat.client.ChatService;
+import com.threerings.crowd.chat.data.ChatMarshaller;
+import com.threerings.crowd.chat.data.ChatMessage;
+import com.threerings.crowd.peer.client.CrowdPeerService;
+import com.threerings.presents.client.Client;
+import com.threerings.presents.data.ClientObject;
+import com.threerings.presents.server.InvocationException;
+import com.threerings.presents.server.InvocationProvider;
+
+/**
+ * Defines the server-side of the {@link CrowdPeerService}.
+ */
+public interface CrowdPeerProvider extends InvocationProvider
+{
+ /**
+ * Handles a {@link CrowdPeerService#deliverTell} request.
+ */
+ public void deliverTell (ClientObject caller, ChatMessage arg1, ChatService.TellListener arg2)
+ throws InvocationException;
+}
diff --git a/src/java/com/threerings/presents/peer/data/ClientInfo.java b/src/java/com/threerings/presents/peer/data/ClientInfo.java
new file mode 100644
index 000000000..dde92254b
--- /dev/null
+++ b/src/java/com/threerings/presents/peer/data/ClientInfo.java
@@ -0,0 +1,43 @@
+//
+// $Id$
+//
+// Narya library - tools for developing networked games
+// Copyright (C) 2002-2006 Three Rings Design, Inc., All Rights Reserved
+// http://www.threerings.net/code/narya/
+//
+// This library is free software; you can redistribute it and/or modify it
+// under the terms of the GNU Lesser General Public License as published
+// by the Free Software Foundation; either version 2.1 of the License, or
+// (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+package com.threerings.presents.peer.data;
+
+import com.threerings.io.SimpleStreamableObject;
+import com.threerings.util.Name;
+
+import com.threerings.presents.dobj.DSet;
+
+/**
+ * Contains information on a particular client.
+ */
+public class ClientInfo extends SimpleStreamableObject
+ implements DSet.Entry
+{
+ /** The username used by this client to authenticate. */
+ public Name username;
+
+ // documentation inherited from interface DSet.Entry
+ public Comparable getKey ()
+ {
+ return username;
+ }
+}
diff --git a/src/java/com/threerings/presents/peer/data/NodeObject.java b/src/java/com/threerings/presents/peer/data/NodeObject.java
new file mode 100644
index 000000000..0262458b4
--- /dev/null
+++ b/src/java/com/threerings/presents/peer/data/NodeObject.java
@@ -0,0 +1,87 @@
+//
+// $Id$
+//
+// Narya library - tools for developing networked games
+// Copyright (C) 2002-2006 Three Rings Design, Inc., All Rights Reserved
+// http://www.threerings.net/code/narya/
+//
+// This library is free software; you can redistribute it and/or modify it
+// under the terms of the GNU Lesser General Public License as published
+// by the Free Software Foundation; either version 2.1 of the License, or
+// (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+package com.threerings.presents.peer.data;
+
+import com.threerings.presents.dobj.DObject;
+import com.threerings.presents.dobj.DSet;
+
+/**
+ * Contains information that one node published for all of its peers.
+ */
+public class NodeObject extends DObject
+{
+ // AUTO-GENERATED: FIELDS START
+ /** The field name of the clients field. */
+ public static final String CLIENTS = "clients";
+ // AUTO-GENERATED: FIELDS END
+
+ /** Contains information on all clients connected to this node. */
+ public DSetclients set. The set will not change until the event is
+ * actually propagated through the system.
+ */
+ public void addToClients (DSet.Entry elem)
+ {
+ requestEntryAdd(CLIENTS, clients, elem);
+ }
+
+ /**
+ * Requests that the entry matching the supplied key be removed from
+ * the clients set. The set will not change until the
+ * event is actually propagated through the system.
+ */
+ public void removeFromClients (Comparable key)
+ {
+ requestEntryRemove(CLIENTS, clients, key);
+ }
+
+ /**
+ * Requests that the specified entry be updated in the
+ * clients set. The set will not change until the event is
+ * actually propagated through the system.
+ */
+ public void updateClients (DSet.Entry elem)
+ {
+ requestEntryUpdate(CLIENTS, clients, elem);
+ }
+
+ /**
+ * Requests that the clients field be set to the
+ * specified value. Generally one only adds, updates and removes
+ * entries of a distributed set, but certain situations call for a
+ * complete replacement of the set value. The local value will be
+ * updated immediately and an event will be propagated through the
+ * system to notify all listeners that the attribute did
+ * change. Proxied copies of this object (on clients) will apply the
+ * value change when they received the attribute changed notification.
+ */
+ public void setClients (DSetsuper.populateBootstrapData before doing their
+ * own populating, however.
+ *
+ * Note: This function will be called on the dobjmgr
+ * thread which means that object manipulations are OK, but client
+ * instance manipulations must be done carefully.
+ */
+ protected void populateBootstrapData (BootstrapData data)
+ {
+ super.populateBootstrapData(data);
+
+ // tell our peer about our node object so they can wire up
+ PeerBootstrapData pdata = (PeerBootstrapData)data;
+ pdata.nodeOid = _peermgr.getNodeObject().getOid();
+ }
+
+ protected PeerManager _peermgr;
}
diff --git a/src/java/com/threerings/presents/peer/server/PeerClientFactory.java b/src/java/com/threerings/presents/peer/server/PeerClientFactory.java
index 555a22fe0..d2c22de34 100644
--- a/src/java/com/threerings/presents/peer/server/PeerClientFactory.java
+++ b/src/java/com/threerings/presents/peer/server/PeerClientFactory.java
@@ -36,8 +36,9 @@ import com.threerings.presents.peer.net.PeerCreds;
*/
public class PeerClientFactory implements ClientFactory
{
- public PeerClientFactory (ClientFactory delegate)
+ public PeerClientFactory (PeerManager peermgr, ClientFactory delegate)
{
+ _peermgr = peermgr;
_delegate = delegate;
}
@@ -45,7 +46,7 @@ public class PeerClientFactory implements ClientFactory
public PresentsClient createClient (AuthRequest areq)
{
if (areq.getCredentials() instanceof PeerCreds) {
- return new PeerClient();
+ return new PeerClient(_peermgr);
} else {
return _delegate.createClient(areq);
}
@@ -61,5 +62,6 @@ public class PeerClientFactory implements ClientFactory
}
}
+ protected PeerManager _peermgr;
protected ClientFactory _delegate;
}
diff --git a/src/java/com/threerings/presents/peer/server/PeerManager.java b/src/java/com/threerings/presents/peer/server/PeerManager.java
index 4f9005c9d..46f2a001b 100644
--- a/src/java/com/threerings/presents/peer/server/PeerManager.java
+++ b/src/java/com/threerings/presents/peer/server/PeerManager.java
@@ -33,8 +33,12 @@ import com.samskivert.util.Invoker;
import com.threerings.presents.client.Client;
import com.threerings.presents.client.ClientObserver;
+import com.threerings.presents.dobj.ObjectAccessException;
+import com.threerings.presents.dobj.Subscriber;
import com.threerings.presents.server.PresentsServer;
+import com.threerings.presents.peer.data.NodeObject;
+import com.threerings.presents.peer.net.PeerBootstrapData;
import com.threerings.presents.peer.net.PeerCreds;
import com.threerings.presents.peer.server.persist.NodeRecord;
import com.threerings.presents.peer.server.persist.NodeRepository;
@@ -51,7 +55,29 @@ public class PeerManager
{
/**
* Creates a peer manager which will create a {@link NodeRepository} which
- * is used to publish our existence and discover the other nodes.
+ * will be used to publish our existence and discover the other nodes.
+ */
+ public PeerManager (ConnectionProvider conprov, Invoker invoker)
+ throws PersistenceException
+ {
+ _invoker = invoker;
+ _noderepo = new NodeRepository(conprov);
+ }
+
+ /**
+ * Returns the distributed object that represents this node to its peers.
+ */
+ public NodeObject getNodeObject ()
+ {
+ return _nodeobj;
+ }
+
+ /**
+ * Initializes this peer manager and initiates the process of connecting to
+ * its peer nodes. This will also reconfigure the ConnectionManager and
+ * ClientManager with peer related bits, so this should not be called until
+ * after the main server has set up its client factory and
+ * authenticator.
*
* @param nodeName this node's unique name.
* @param sharedSecret a shared secret used to allow the peers to
@@ -62,46 +88,32 @@ public class PeerManager
* @param invoker we will perform all database operations on the supplied
* invoker thread.
*/
- public PeerManager (
- String nodeName, String sharedSecret, String hostName, int port,
- ConnectionProvider conprov, Invoker invoker)
- throws PersistenceException
+ public void init (String nodeName, String sharedSecret,
+ String hostName, int port)
{
_nodeName = nodeName;
_hostName = hostName;
_port = port;
_sharedSecret = sharedSecret;
- _invoker = invoker;
- _noderepo = new NodeRepository(conprov);
- }
- /**
- * Instructs the node manager to load up information about its other nodes
- * and attempt to establish connections with those nodes.
- */
- public void init ()
- {
- // first register ourselves with the node table
- _invoker.postUnit(new Invoker.Unit() {
- public boolean invoke () {
- NodeRecord record = new NodeRecord(_nodeName, _hostName, _port);
- try {
- _noderepo.updateNode(record);
- } catch (PersistenceException pe) {
- log.warning("Failed to register node record " +
- "[rec=" + record + ", error=" + pe + "].");
- }
- return false;
+ // wire ourselves into the server
+ PresentsServer.conmgr.setAuthenticator(
+ new PeerAuthenticator(
+ this, PresentsServer.conmgr.getAuthenticator()));
+ PresentsServer.clmgr.setClientFactory(
+ new PeerClientFactory(
+ this, PresentsServer.clmgr.getClientFactory()));
+
+ // create our node object
+ Class