Main Page | Modules | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Class Members | Related Pages | Examples

6. Actions sent from Client-object to Server-object

This test will set up a ServerData object on the server, replicate it to the client, and then the client will call the ClientData::updatePacket(ClientFramework * f, char updatetype, FrameworkPacket * packet) method to send an action back the server-version of the object.

Client Application

In this example you should notice the implementation of the member method:
MyClientData::sendSomeAction();
This is the method that sends an action to the server. The parameters for constructing a packet are described in the source.

/// @cond EXCLUDEDTESTSOURCES
/***************************************************************************
 * The contents of this file are subject to the Mozilla Public             *
 * License Version 1.1 (the "License"); you may not use this file          *
 * except in compliance with the License. You may obtain a copy of         *
 * the License at http://www.mozilla.org/MPL/                              *
 *                                                                         *
 * Software distributed under the License is distributed on an "AS         *
 * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or              *
 * implied. See the License for the specific language governing            *
 * rights and limitations under the License.                               *
 *                                                                         *
 * The Original Code is Game Network Framework (GaNeF).                    *
 *                                                                         *
 * The Initial Developers of the Original Code are                         *
 * Lars Langer and Emanuel Greisen                                         *
 * Copyright (C) 2005. Lars Langer & Emanuel Greisen                       *
 * All Rights Reserved.                                                    *
 *                                                                         *
 * Contributor(s):                                                         *
 *   none yet....                                                          *
 *                                                                         *
 ***************************************************************************/

#include <iostream>
#include <cstdlib>

#include "../Ganef/client/clientframework.h"
#include "../Ganef/client/clientdata.h"


class MyClientData : public ClientData
{
   public:
      MyClientData(ClientFramework * f, ClientPacket * p) : ClientData(f,p)
      {
      }
      virtual void updatePacket(ClientFramework * f, unsigned char updatetype, ClientPacket * p)
      {
         // We receive no updates in this test
      }

      static ClientData * constructMyClientData(ClientFramework * f, ClientPacket * p)
      {
         return new MyClientData(f,p);
      }

      void sendSomeAction() const
      {
         // The first parameter is the object it self, then commes the action type
         // (4-255), then the priority (0-255) and last if it should be sent reliable
         ClientPacket * p = new ClientPacket(this, 10, 12, false);
         p->writeInt32(12);
         p->writeInt32(14);
         enqueuePacket(p);
      }
};


/**
 * This is just a test-client-framework.
 * @author Lars Langer and Emanuel Greisen
 */
class TestClientFramework : public ClientFramework
{
   private:
      bool is_running;
      std::string server_hostname;

   public:
      TestClientFramework(const std::string & server_hostname) : ClientFramework(int(0)),server_hostname(server_hostname)
      {
         registerConstructor(0x424242, MyClientData::constructMyClientData);
      }
      ~TestClientFramework()
      {
      };

   protected: // These must be implemented in a derived class
      virtual void writeHandshakeInitMessage( ClientPacket * fp ){}
      virtual void onHandshakingDiscontinue( ClientPacket * fp ){}
      virtual bool onHandshakeDescription( ClientPacket * fp, ClientPacket * reply )
      {
         return true;
      }
      virtual void onDisconnect( ) { std::cout << "Disconnected\n"; }
      virtual void onConnect( ){ std::cout << "Connected\n"; }

   public:
      void mainLoop( )
      {
         std::cout << "Connecting to: " << server_hostname <<":"<< 8000<< std::endl;
         initServerConnection(server_hostname, 8000);
         is_running = true;
         while(is_running)
         {
            // Get/handle Packets from the framework
            keepAlive();

            // Here we iterate over all data-objects in the framework
            // Please note: the typecast here is DANGEROUS, the only reason
            // we can do it is that we KNOW FOR SURE that all objects are of
            // class MyClientData
            std::map<unsigned int, ClientData *>::const_iterator it;
            for(it = getClientDataObjects().begin(); it != getClientDataObjects().end(); ++it)
            {
               MyClientData * dataobj = dynamic_cast<MyClientData *>(it->second);
               if(dataobj)
               {
                  dataobj->sendSomeAction();
               }
            }

            // Then we sleep to let the CPU live
            psleep(50);
         }
      }
};




int main(int argc, char *argv[])
{
   std::string server_host("localhost");
   if(argc > 1)
      server_host = argv[1];
   TestClientFramework app(server_host);

   // Start the Application
   app.mainLoop();
}

/// @endcond

Server Application

This test-server does not do much, it just prints out the actions when they are received. The actions are received in the virtual method:
virtual void clientPacket(Client * client, unsigned char type, ServerPacket * packet);

/// @cond EXCLUDEDTESTSOURCES
/***************************************************************************
 * The contents of this file are subject to the Mozilla Public             *
 * License Version 1.1 (the "License"); you may not use this file          *
 * except in compliance with the License. You may obtain a copy of         *
 * the License at http://www.mozilla.org/MPL/                              *
 *                                                                         *
 * Software distributed under the License is distributed on an "AS         *
 * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or              *
 * implied. See the License for the specific language governing            *
 * rights and limitations under the License.                               *
 *                                                                         *
 * The Original Code is Game Network Framework (GaNeF).                    *
 *                                                                         *
 * The Initial Developers of the Original Code are                         *
 * Lars Langer and Emanuel Greisen                                         *
 * Copyright (C) 2005. Lars Langer & Emanuel Greisen                       *
 * All Rights Reserved.                                                    *
 *                                                                         *
 * Contributor(s):                                                         *
 *   none yet....                                                          *
 *                                                                         *
 ***************************************************************************/

#include <iostream>
#include <cstdlib>
#include <vector>


#include "../Ganef/server/serverframework.h"


class MyServerData : public ServerData
{
   private:
      std::string name;
   public:
      // The two last parameters for ServerData is the priority of its updatepackets
      //  and wether they should be sent reliable.
      MyServerData(ServerFramework * fw, const std::string & name) : ServerData(fw, 10, false),name(name)
      {
      };
   public:
      virtual const unsigned int getClassId() const { return 0x424242; };
      virtual void fillUpdatePacket(ServerPacket * packet, unsigned char type) const
      {
         // We send no updates
      }
      virtual void fillCreateObjectPacket(ServerPacket * packet) const
      {
         // We contain no data
      }
      /// Called when ever we receive a packet for this object from a client.
      virtual void clientPacket(Client * client, unsigned char type, ServerPacket * p)
      {
         switch(type)
         {
            case 10:
               int x = p->readInt32();
               int y = p->readInt32();
               std::cout << "Client["<<client->getId()<<"] sent: (x:"<<x<<",y:"<<y<<") to obj:"<<name<< std::endl;
               break;
         }
      }
};

/**
 * This is just a test server-framework;
 * @author Lars Langer and Emanuel Greisen
 */
class TestServerFramework : public ServerFramework
{
   public:
      TestServerFramework() : ServerFramework(8000)
      {
      }

      ~TestServerFramework()
      {
      }

   protected: // These method should be implemented on the GameServer
      virtual bool onInitialHandshake(ServerPacket * handshake, ServerPacket * reply)
      {
         return true; // Accept all clients.
      }
      virtual void onClientConnected(Client * client)
      {
         std::cout << "Client: " << client->getId() << " connected\n";
      }
      virtual void onClientDisconnected(Client * client)
      {
         std::cout << "Client: " << client->getId() << " disconnected\n";
      }
      virtual Client * createClient(const ipaddress &addr, int port)
      {
         Client * client = new Client(this, addr, port);
         // Here we send the construction packages for all Framework Data
         std::map<unsigned int, ServerData *>::const_iterator it;
         for(it = getServerDataObjects().begin(); it != getServerDataObjects().end(); ++it)
         {
            ServerData * s_data = it->second;
            s_data->sendCreateObject(client);
         }

         return client;
      }

   public:
      void mainLoop()
      {
         std::cout << "TestServerFramework: Running\n";
         MyServerData mydata1(this, "MyData1");
         MyServerData mydata2(this, "MyData2");
         MyServerData mydata3(this, "MyData3");
         while(true)
         {
            // Get all incomming messages
            keepAlive();

            // Sleep a little
            psleep(100);
         }
      }
};




int main(int argc, char *argv[])
{
   try
   {
      // Create a framework
      TestServerFramework framework;

      // Start the framework
      framework.start();

      // GameLoop
      framework.mainLoop();
   }
   catch(FrameworkError *err)
   {
      std::cout << "FrameworkError:" << err->msg << std::endl;
   }
   catch(PacketError *err)
   {
      std::cout << "PacketError:" << err->msg << std::endl;
   }

   return EXIT_SUCCESS;
}

/// @endcond

Generated on Mon Feb 6 12:24:58 2006 for Ganef by  doxygen 1.4.4