Created an abstract hosted connection service that has

the autohost, start/stopHostingOnConnection support built
into it.  This is a very common things for connection based
services and I got tired of cutting/pasting it all the time.
RpcHostedService was modified to extend this base class
instead of the more basic one.
experimental
Paul Speed 10 years ago
parent fb3a1902a8
commit 4bd774a653
  1. 148
      jme3-networking/src/main/java/com/jme3/network/service/AbstractHostedConnectionService.java
  2. 62
      jme3-networking/src/main/java/com/jme3/network/service/rpc/RpcHostedService.java

@ -0,0 +1,148 @@
/*
* Copyright (c) 2015 jMonkeyEngine
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jme3.network.service;
import com.jme3.network.HostedConnection;
import com.jme3.network.Server;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* Convenient base class for HostedServices providing some default HostedService
* interface implementations as well as a few convenience methods
* such as getServiceManager() and getService(type). This implementation
* enhances the default capabilities provided by AbstractHostedService by
* adding automatic connection management.
*
* <p>Subclasses must at least override the onInitialize(), startHostingOnConnection(), and
* stopHostingOnConnection() methods to handle service and connection initialization.</p>
*
* <p>An autoHost flag controls whether startHostingOnConnection() is called
* automatically when new connections are detected. If autoHohst is false then it
* is up to the implementation or appliction to specifically start hosting at
* some point.</p>
*
* @author Paul Speed
*/
public abstract class AbstractHostedConnectionService extends AbstractHostedService {
static final Logger log = Logger.getLogger(AbstractHostedConnectionService.class.getName());
private boolean autoHost;
/**
* Creates a new HostedService that will autohost connections
* when detected.
*/
protected AbstractHostedConnectionService() {
this(true);
}
/**
* Creates a new HostedService that will automatically host
* connections only if autoHost is true.
*/
protected AbstractHostedConnectionService( boolean autoHost ) {
this.autoHost = autoHost;
}
/**
* When set to true, all new connections will automatically have
* hosting services attached to them by calling startHostingOnConnection().
* If this is set to false then it is up to the application or other services
* to eventually call startHostingOnConnection().
*
* <p>Reasons for doing this vary but usually would be because
* the client shouldn't be allowed to perform any service-related calls until
* it has provided more information... for example, logging in.</p>
*/
public void setAutoHost( boolean b ) {
this.autoHost = b;
}
/**
* Returns true if this service automatically attaches
* hosting capabilities to new connections.
*/
public boolean getAutoHost() {
return autoHost;
}
/**
* Performs implementation specific connection hosting setup.
* Generally this involves setting up some handlers or session
* attributes on the connection. If autoHost is true then this
* method is called automatically during connectionAdded()
* processing.
*/
public abstract void startHostingOnConnection( HostedConnection hc );
/**
* Performs implementation specific connection tear-down.
* This will be called automatically when the connectionRemoved()
* event occurs... whether the application has already called it
* or not.
*/
public abstract void stopHostingOnConnection( HostedConnection hc );
/**
* Called internally when a new connection is detected for
* the server. If the current autoHost property is true then
* startHostingOnConnection(hc) is called.
*/
@Override
public void connectionAdded(Server server, HostedConnection hc) {
if( log.isLoggable(Level.FINEST) ) {
log.log(Level.FINEST, "connectionAdded({0}, {1})", new Object[]{server, hc});
}
if( autoHost ) {
startHostingOnConnection(hc);
}
}
/**
* Called internally when an existing connection is leaving
* the server. This method always calls stopHostingOnConnection(hc).
* Implementations should be aware that if they stopHostingOnConnection()
* early that they will get a second call when the connection goes away.
*/
@Override
public void connectionRemoved(Server server, HostedConnection hc) {
if( log.isLoggable(Level.FINEST) ) {
log.log(Level.FINEST, "connectionRemoved({0}, {1})", new Object[]{server, hc});
}
stopHostingOnConnection(hc);
}
}

@ -35,8 +35,8 @@ package com.jme3.network.service.rpc;
import com.jme3.network.HostedConnection;
import com.jme3.network.Server;
import com.jme3.network.serializing.Serializer;
import com.jme3.network.service.AbstractHostedConnectionService;
import com.jme3.network.util.SessionDataDelegator;
import com.jme3.network.service.AbstractHostedService;
import com.jme3.network.service.HostedServiceManager;
import com.jme3.network.service.rpc.msg.RpcCallMessage;
import com.jme3.network.service.rpc.msg.RpcResponseMessage;
@ -62,13 +62,12 @@ import java.util.logging.Logger;
*
* @author Paul Speed
*/
public class RpcHostedService extends AbstractHostedService {
public class RpcHostedService extends AbstractHostedConnectionService {
private static final String ATTRIBUTE_NAME = "rpcSession";
static final Logger log = Logger.getLogger(RpcHostedService.class.getName());
private boolean autoHost;
private SessionDataDelegator delegator;
/**
@ -87,7 +86,7 @@ public class RpcHostedService extends AbstractHostedService {
* on the specified 'autoHost' flag.
*/
public RpcHostedService( boolean autoHost ) {
this.autoHost = autoHost;
super(autoHost);
// This works for me... has to be different in
// the general case
@ -115,31 +114,6 @@ public class RpcHostedService extends AbstractHostedService {
}
}
/**
* When set to true, all new connections will automatically have
* RPC hosting services attached to them, meaning they can send
* and receive RPC calls. If this is set to false then it is up
* to other services to eventually call startHostingOnConnection().
*
* <p>Reasons for doing this vary but usually would be because
* the client shouldn't be allowed to perform any RPC calls until
* it has provided more information. In general, this is unnecessary
* because the RpcHandler registries are not shared. Each client
* gets their own and RPC calls will fail until the appropriate
* objects have been registtered.</p>
*/
public void setAutoHost( boolean b ) {
this.autoHost = b;
}
/**
* Returns true if this service automatically attaches RPC
* hosting capabilities to new connections.
*/
public boolean getAutoHost() {
return autoHost;
}
/**
* Retrieves the RpcConnection for the specified HostedConnection
* if that HostedConnection has had RPC services started using
@ -157,6 +131,7 @@ public class RpcHostedService extends AbstractHostedService {
* This method is called automatically for all new connections if
* autohost is set to true.
*/
@Override
public void startHostingOnConnection( HostedConnection hc ) {
if( log.isLoggable(Level.FINEST) ) {
log.log(Level.FINEST, "startHostingOnConnection:{0}", hc);
@ -173,6 +148,7 @@ public class RpcHostedService extends AbstractHostedService {
* This method is called automatically for all leaving connections if
* autohost is set to true.
*/
@Override
public void stopHostingOnConnection( HostedConnection hc ) {
RpcConnection rpc = hc.getAttribute(ATTRIBUTE_NAME);
if( rpc == null ) {
@ -195,33 +171,5 @@ public class RpcHostedService extends AbstractHostedService {
server.removeMessageListener(delegator, delegator.getMessageTypes());
}
/**
* Called internally when a new connection is detected for
* the server. If the current autoHost property is true then
* startHostingOnConnection(hc) is called.
*/
@Override
public void connectionAdded(Server server, HostedConnection hc) {
if( log.isLoggable(Level.FINEST) ) {
log.log(Level.FINEST, "connectionAdded({0}, {1})", new Object[]{server, hc});
}
if( autoHost ) {
startHostingOnConnection(hc);
}
}
/**
* Called internally when an existing connection is leaving
* the server. If the current autoHost property is true then
* stopHostingOnConnection(hc) is called.
*/
@Override
public void connectionRemoved(Server server, HostedConnection hc) {
if( log.isLoggable(Level.FINEST) ) {
log.log(Level.FINEST, "connectionRemoved({0}, {1})", new Object[]{server, hc});
}
stopHostingOnConnection(hc);
}
}

Loading…
Cancel
Save