[skycastle-commits] SF.net SVN: skycastle: [444] trunk/skycastle/modules

  • From: zzorn@xxxxxxxxxxxxxxxxxxxxx
  • To: skycastle-commits@xxxxxxxxxxxxx
  • Date: Sat, 05 Apr 2008 15:09:23 -0700

Revision: 444
          http://skycastle.svn.sourceforge.net/skycastle/?rev=444&view=rev
Author:   zzorn
Date:     2008-04-05 15:09:23 -0700 (Sat, 05 Apr 2008)

Log Message:
-----------
Implemented protocol negotiation to the client too.  Now the only major missing 
thing on the client side is the UI.

Modified Paths:
--------------
    
trunk/skycastle/modules/client/src/main/java/org/skycastle/client/SkycastleClient.java
    
trunk/skycastle/modules/core/src/main/java/org/skycastle/protocol/ProtocolCommunicator.java
    
trunk/skycastle/modules/server/src/main/java/org/skycastle/server/SkycastleClientSessionHandler.java

Modified: 
trunk/skycastle/modules/client/src/main/java/org/skycastle/client/SkycastleClient.java
===================================================================
--- 
trunk/skycastle/modules/client/src/main/java/org/skycastle/client/SkycastleClient.java
      2008-04-05 21:40:12 UTC (rev 443)
+++ 
trunk/skycastle/modules/client/src/main/java/org/skycastle/client/SkycastleClient.java
      2008-04-05 22:09:23 UTC (rev 444)
@@ -6,15 +6,19 @@
 import com.sun.sgs.client.simple.SimpleClientListener;
 import org.skycastle.core.GameContext;
 import org.skycastle.messaging.Message;
+import org.skycastle.messaging.modifications.ModificationMessage;
 import org.skycastle.messaging.updates.UpdateMessage;
+import org.skycastle.protocol.ProtocolCommunicator;
 import org.skycastle.protocol.ProtocolException;
 import org.skycastle.protocol.negotiation.ClientSideProtocolNegotiator;
-import org.skycastle.protocol.negotiation.ProtocolNegotiator;
+import org.skycastle.protocol.negotiation.NegotiationStatus;
 import org.skycastle.protocol.registry.ProtocolRegistryImpl;
 
+import javax.swing.*;
 import java.io.IOException;
 import java.net.PasswordAuthentication;
 import java.util.Properties;
+import java.util.logging.Level;
 import java.util.logging.Logger;
 
 /**
@@ -43,20 +47,26 @@
 // --> We need the possibility of a ProxyGameObject to be of some specified 
subtype, that is specified by the server.
 // Or maybe they could be POJO game objects..
 // They should implement some interface that has getJComponent and similar 
methods
-// So client could do something like 
getAccountObject().getUiRoot().createJComponent()    
+// So client could do something like 
getAccountObject().getUiRoot().createJComponent()
+
+// Supress warning about missing serialVersionUID,
+// as this implementation of ProtocolCommunicator is not intended to be 
serizliaed.
+@SuppressWarnings( { "serial" } )
 public class SkycastleClient
+        extends ProtocolCommunicator
         implements SimpleClientListener
 {
 
     //======================================================================
     // Private Fields
 
-    private final SimpleClient myDarkstarClient;
-    private final ProtocolNegotiator myProtocolNegotiator;
+    @SuppressWarnings( { "NonSerializableFieldInSerializableClass" } )
+    private final SimpleClient mySimpleClient;
 
     //======================================================================
     // Private Constants
 
+    private static final int PROTOCOL_NEGOTIATION_TIMEOUT_MS = 10000;
     /**
      * The name of the host property.
      */
@@ -80,10 +90,9 @@
     private static final String TEST_USER_NAME = "TestUser";
 
     /**
-     * The {@link java.util.logging.Logger} for this class.
+     * The {@link Logger} for this class.
      */
-    private static final Logger LOGGER =
-            Logger.getLogger( SkycastleClient.class.getName() );
+    private static final Logger LOGGER = Logger.getLogger( 
SkycastleClient.class.getName() );
     private static final String CLIENT_TYPE = "SkycastleClient";
     private static final String CLIENT_VERSION = "0.1";
     private static final ProtocolRegistryImpl PROTOCOL_REGISTRY = new 
ProtocolRegistryImpl();
@@ -99,14 +108,15 @@
      */
     public SkycastleClient()
     {
-        myDarkstarClient = new SimpleClient( this );
+        super( new ClientSideProtocolNegotiator( PROTOCOL_REGISTRY,
+                                                 CLIENT_TYPE,
+                                                 CLIENT_VERSION ),
+               PROTOCOL_NEGOTIATION_TIMEOUT_MS );
 
+        mySimpleClient = new SimpleClient( this );
+
         // DEBUG: For now, just try directly to log in.
         login();
-
-        myProtocolNegotiator = new ClientSideProtocolNegotiator( 
PROTOCOL_REGISTRY,
-                                                                 CLIENT_TYPE,
-                                                                 
CLIENT_VERSION );
     }
 
     //----------------------------------------------------------------------
@@ -114,7 +124,7 @@
 
     public ClientChannelListener joinedChannel( final ClientChannel 
clientChannel )
     {
-        LOGGER.fine( "Joined channel '" + clientChannel + "'." );
+        LOGGER.info( "Joined channel '" + clientChannel + "'." );
 
         return null;
     }
@@ -122,59 +132,32 @@
 
     public void receivedMessage( final byte[] serverMessage )
     {
-        if ( myProtocolNegotiator.getStatus().isFinished() )
+        try
         {
-            try
-            {
-                final Message message = 
myProtocolNegotiator.getProtocol().decode( serverMessage );
-
-                // TODO: Validate message to ensure a rogue server is not 
sending us trojans
-                // message.validate(  )
-
-                // TODO: Check that the message is an update message, as the 
client should only get those.
-                final UpdateMessage updateMessage = (UpdateMessage) message;
-
-                // Apply the update message to the client side model
-                // TODO: Use cient side GameContext directly instead, and 
specify a namespace prefix for this server and account
-                updateMessage.applyStateChangeToModel( 
GameContext.getGameObjectContext() );
-            }
-            catch ( ProtocolException e )
-            {
-                // TODO: Notify user, reset server connection?
-                e.printStackTrace();  //To change body of catch statement use 
File | Settings | File Templates.
-            }
+            handleReceivedEncodedMessage( serverMessage );
         }
-        else
+        catch ( ProtocolException e )
         {
-            final byte[] reply = myProtocolNegotiator.handleMessage( 
serverMessage );
-            try
-            {
-                myDarkstarClient.send( reply );
-            }
-            catch ( IOException e )
-            {
-                // TODO: Notify user, reset server connection?
-                e.printStackTrace();  //To change body of catch statement use 
File | Settings | File Templates.
-            }
+            LOGGER.warning( "Problem when decoding incoming message from 
server: " + e.getMessage() );
         }
     }
 
 
     public void reconnecting()
     {
-        LOGGER.fine( "Reconnecting" );
+        LOGGER.info( "Reconnecting" );
     }
 
 
     public void reconnected()
     {
-        LOGGER.fine( "Reconnected" );
+        LOGGER.info( "Reconnected" );
     }
 
 
     public void disconnected( final boolean b, final String s )
     {
-        LOGGER.fine( "Disconnected.  Graceful: '" + b + "'.  Message: '" + s + 
"'." );
+        LOGGER.info( "Disconnected.  Graceful: '" + b + "'.  Message: '" + s + 
"'." );
     }
 
     //----------------------------------------------------------------------
@@ -191,28 +174,105 @@
 
     public void loggedIn()
     {
-        LOGGER.fine( "Logged In" );
+        LOGGER.info( "Logged In.  Now negotiationg protocol..." );
 
-        if ( myProtocolNegotiator.startsNegotiations() )
+        startProtocolNegotiations();
+    }
+
+
+    public void loginFailed( final String s )
+    {
+        LOGGER.info( "Login Failed.  Reason: '" + s + "'." );
+    }
+
+    //======================================================================
+    // Protected Methods
+
+    @Override
+    protected void scheduleTimeoutCallback( final long timeout_ms )
+    {
+        final Thread timeoutTimer = new Thread( new Runnable()
         {
-            try
+
+            public void run()
             {
-                myDarkstarClient.send( myProtocolNegotiator.handleMessage( 
null ) );
+                try
+                {
+                    Thread.sleep( timeout_ms );
+                }
+                catch ( InterruptedException e )
+                {
+                    // We were interrupted for some reason.  Stop waiting, and 
call the timeout.
+                }
+
+                // TODO: Assumes that the main game loop will run in the Swing 
event thread.  Check this.
+                SwingUtilities.invokeLater( new Runnable()
+                {
+
+                    public void run()
+                    {
+                        onTimeoutCallback();
+                    }
+
+                } );
             }
-            catch ( IOException e )
-            {
-                // TODO: Notify user about failure, reset server connection?
-                e.printStackTrace();  //To change body of catch statement use 
File | Settings | File Templates.
-            }
+
+        } );
+
+        timeoutTimer.setDaemon( true ); // If the program exists, don't stay 
to wait for the timeout.
+
+        timeoutTimer.start();
+    }
+
+
+    @Override
+    protected void sendEncodedMessage( final byte[] encodedMessage )
+    {
+        try
+        {
+            mySimpleClient.send( encodedMessage );
         }
+        catch ( IOException e )
+        {
+            LOGGER.log( Level.WARNING, "Problem when sending an encoded 
message to the server.", e );
+        }
     }
 
 
-    public void loginFailed( final String s )
+    @Override
+    protected void onProtocolNegotiationFailed( final NegotiationStatus status 
)
     {
-        LOGGER.fine( "Login Failed.  Reason: '" + s + "'." );
+        LOGGER.severe( "Could not negotiate a common protocol with the server: 
" + status.toString() );
     }
 
+
+    @Override
+    protected void onProtocolNegotiationSucceeded( final String protocolId )
+    {
+        LOGGER.info( "Protocol negotiated." );
+    }
+
+
+    @Override
+    protected void onMessage( final Message message ) throws ProtocolException
+    {
+        if ( message instanceof UpdateMessage )
+        {
+            final UpdateMessage updateMessage = (UpdateMessage) message;
+
+            updateMessage.applyStateChangeToModel( 
GameContext.getGameObjectContext() );
+        }
+        else if ( message instanceof ModificationMessage )
+        {
+            throw new ProtocolException(
+                    "The client does not accept any ModificationMessages, only 
UpdateMessages, but the incoming message was: " + message );
+        }
+        else
+        {
+            throw new ProtocolException( "Unknown message type: " + 
message.getClass() );
+        }
+    }
+
     //======================================================================
     // Private Methods
 
@@ -220,6 +280,7 @@
      * Initiates asynchronous login to the SGS server specified by the host 
and port properties.
      */
     // IDEA: This could be one action provided by a client side GameObject 
representing a server
+    @SuppressWarnings( { "AccessOfSystemProperties" } )
     private void login()
     {
         final String host = System.getProperty( HOST_PROPERTY, DEFAULT_HOST );
@@ -230,12 +291,12 @@
             final Properties connectProps = new Properties();
             connectProps.setProperty( "host", host );
             connectProps.setProperty( "port", port );
-            myDarkstarClient.login( connectProps );
+            mySimpleClient.login( connectProps );
         }
         catch ( Exception e )
         {
-            // TODO: Report error to user
-            e.printStackTrace();
+            LOGGER.log( Level.SEVERE, "Problem when connecting to the 
server.", e );
+
             disconnected( false, e.getMessage() );
         }
     }

Modified: 
trunk/skycastle/modules/core/src/main/java/org/skycastle/protocol/ProtocolCommunicator.java
===================================================================
--- 
trunk/skycastle/modules/core/src/main/java/org/skycastle/protocol/ProtocolCommunicator.java
 2008-04-05 21:40:12 UTC (rev 443)
+++ 
trunk/skycastle/modules/core/src/main/java/org/skycastle/protocol/ProtocolCommunicator.java
 2008-04-05 22:09:23 UTC (rev 444)
@@ -70,7 +70,7 @@
      * Starts the negotiation timeout, and sends opening message to the other 
party (depending on the {@link
      * ProtocolNegotiator} type).
      */
-    public final void startNegotiations()
+    public final void startProtocolNegotiations()
     {
         if ( myNegotiationsStarted )
         {
@@ -97,7 +97,7 @@
      * Should be called after the time specified amount of time after 
scheduleTimeoutCallback is called. Used
      * to check if the protocol negotiation timed out.
      */
-    public final void timeoutCallback()
+    public final void onTimeoutCallback()
     {
         if ( !myProtocolNegotiator.getStatus().isFinished() )
         {

Modified: 
trunk/skycastle/modules/server/src/main/java/org/skycastle/server/SkycastleClientSessionHandler.java
===================================================================
--- 
trunk/skycastle/modules/server/src/main/java/org/skycastle/server/SkycastleClientSessionHandler.java
        2008-04-05 21:40:12 UTC (rev 443)
+++ 
trunk/skycastle/modules/server/src/main/java/org/skycastle/server/SkycastleClientSessionHandler.java
        2008-04-05 22:09:23 UTC (rev 444)
@@ -80,7 +80,7 @@
 
         myClientSession = clientSession;
 
-        startNegotiations();
+        startProtocolNegotiations();
     }
 
     //----------------------------------------------------------------------
@@ -127,7 +127,7 @@
 
     public void run() throws Exception
     {
-        timeoutCallback();
+        onTimeoutCallback();
     }
 
     //======================================================================


This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.

Other related posts:

  • » [skycastle-commits] SF.net SVN: skycastle: [444] trunk/skycastle/modules