<A HREF="agentkit_contents.html"><img align=center src="contents.gif" ALT="Contents"></A> Up Previous Next

Creating an agent server

In the following explanation, C++ notation is used, but the same behaviour can be assumed for CLIPS programs.

To create a server, you need to derive from two classes, agServer and agConnection.

When you have created an instance of your server object, you must call the Create function with a server name. The server will then wait (in the normal message loop) for incoming connections. When a connection is requested, OnAcceptConnection will create a connection object which will intercept messages sent by the client.

When a client agent wishes the server to execute a KQML command, it will call KQMLExecute on its end of the connection. At the server side, OnKQMLExecute is called, and the server agent should interpret the KQML appropriately. The server agent puts a result on the server result list, to be queried by the client at its leisure, and notifies the client (with KQMLAdvise) that the task has been completed.

The server's connection object(s) will be deleted automatically when the client breaks the connection with Disconnect. The connection can be held for the duration of several messages, or the client can opt to keep making and breaking connections with each message.

The following is an example fragment of a simple server agent.

  class MyServer;
  class MyConnection;

  MyServer *my_server = NULL;
  MyConnection *the_connection = NULL;

  class MyConnection: public agConnection
  {
   public:
    MyConnection(wxIPCObject *clientOrServer);
    ~MyConnection(wxIPCObject *clientOrServer);
    Bool OnKQMLExecute(expression *kqml);
  };

  class MyServer: public agServer
  {
   public:
    wxConnection *OnAcceptConnection(char *topic)
    {
      return new MyConnection(this);
    }
   };

  MyConnection::MyConnection(wxIPCObject *clientOrServer):agConnection(clientOrServer)
  {
    if (frame)
      (*frame->textWindow) << "Incoming connection made.\n";
    the_connection = this;
  }

  MyConnection::~MyConnection(void)
  {
    if (frame)
      (*frame->textWindow) << "Incoming connection broken.\n";

    the_connection = NULL;
  }

  Bool MyConnection::OnKQMLExecute(expression *kqml)
  {
    long taskId;
    // Interpret the KQML, somehow.
    expression *result = MyInterpretKQML(kqml, &taskId);
    if (result)
    {
      my_server->AddResult(result, taskId);
      return TRUE;
    }
    else
      return FALSE;
  }

  // MAIN PROGRAM

  // Create a new server
  MyServer *my_server = new MyServer;
  my_server->Create("MyServerName");