This repository has been archived on 2025-01-04. You can view files and clone it, but cannot push or open issues or pull requests.
lwb6/legacyworlds/doc/communications.txt
Emmanuel BENOîT a4bce68b17 Client/server communications overview
* Added a text file which describes the current client/server protocol,
and the implementation of both the protocol itself and the server-level
support. It also includes a discussion of what is wrong with the current
implementation.
2012-01-24 16:08:30 +01:00

134 lines
No EOL
6.2 KiB
Text

Communications between the server and its clients
==================================================
This file contains a few notes about the implementation of the client/server
system, as well as a (purely speculative) section about changes that ought to
be made.
Definitions
------------
The Legacy Worlds "server" has nothing to do with the web interfaces. It is a
standalone application which handles most aspects of the game itself, but does
not provide any kind of human-readable interface.
Legay Worlds "clients", on the other hand, are applications (whether they are
standalone or depend on some container is a detail) which connect to the
server and provide either some user interface or an intermediary layer for
an user interface application.
At this time, the two clients in existence are:
-> the main web site,
-> the administration web site.
This architecture was designed to keep any access to the game completely
separate from the game's logic. The only exception to that principle is the
email notifications system (see discussion).
Protocol implementation
------------------------
All client/server communications go through a RMI interface, SessionAccessor.
This interface can be used by clients to initiate, authenticate and terminate
sessions and to execute commands on the server. The general type of a session
(i.e. whether it is an administrative session, a game session, or an
"external" session which serves for user registration) is determined when the
session is created.
Commands are classes that extend the Command abstract class. They carry all
the information required for their specific purpose.
In response to a Command, the server will reply with either an exception or
a response. The following exceptions can be thrown by the server:
-> SessionInternalException means that some internal error occurred while
manipulating the session or executing the command. It can in theory be
thrown by all parts of the session access interface, but shouldn't
occur too often in practice, as it indicates a bug or server problem.
-> SessionIdentifierException means that the session identifier sent by
the client doesn't match any known session. This may indicate a timeout
on the client's part.
-> SessionStateException is thrown when the client tries to re-authenticate
a session or to execute a command before the session has been
authenticated.
-> SessionCommandException is thrown when the command that was sent is not
supported by the server.
When everything is fine, a command's execution will cause the server to return
an object of some class that inherits the CommandResponse class. If no data is
to be transmitted in response to the command, the response may be a
NullResponse instance.
Server implementation
----------------------
The server supports various types of session. Each type of session may have
different parameters (for example, its timeout) or behaviours (for example,
the way the session's authentication request is verified). In addition, each
type of session will implement a different set of commands.
The internals of the session and command routing system are somewhat outside
the scope of this document. The various classes which implement that system
can be found in com.deepclone.lw.beans.user.abst for the most basic elements,
while the com.deepclone.lw.beans.user.admin,
com.deepclone.lw.beans.user.player and com.deepclone.lw.beans.user.ext
packages all contain parts specific to session types.
Actual command handling is defined through classes which implement the
AutowiredCommandDelegate interface.
-> The getCommandHandler() method must return the class which defines the
type of session in which the command handler is to be included. For
example it will return GameSubTypeBean.class for game session commands or
AdminCommandsBean.class for administration commands.
-> The getType() method must return the class of commands handled. For
example, a handler for commands of the WhateverCommand class would have
this method returning WhateverCommand.class
-> Finally, the execute() method implements the command itself.
All command handlers, once defined, must be listed to one of the Spring XML
configuration files in the legacyworlds-server-beans-user project's resources.
Discussion
-----------
While the current implementation is successful in that it defines a clear line
between the game and whatever is used to display it and access it, it has a
few drawbacks.
Firstly, the use of RMI associated with dozens of Command / CommandResponse
classes, while easy to use, is definitely very heavy, specific to Java and
causes a proliferation of mostly-useless classes.
The protocol's weight is not too problematic at this time, since all
communications occur either on the same system or between virtual machines
running on the same system. However, the unbelievable amount of classes
makes the implementation of new commands or the modification of existing
commands somewhat tedious. Finally, the Java specificity would prevent the
implementation of clients connecting directly to the server in any other
language.
However the main problem with this implementation lies elsewhere. As a matter
of fact, communications between client and server only go one way: the clients
may request the execution of commands, but the server cannot send the clients
data independently. It is not possible to "poll" the server either: sessions
are exclusive and can only be used to execute one command at a time, so having
one session running a blocking command is not a possibility. The only way a
client application could request updates would be by running a command every
few seconds. This is not a problem at all with the current clients, as they
are based on user-triggered HTTP requests.
However, trying to implement anything more interactive would be difficult. As
a matter of fact, the email notifications system should *be* a separate
client, but the current architecture does not support it.
In the long run, the existing communications protocol should be replaced with
something more flexible. For example, it is entirely conceivable to replace it
with a custom TCP- or even UDP-based protocol which could be used by both
"local" clients (such as the web sites) and remote applications.