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.
This commit is contained in:
parent
4e27875d87
commit
a4bce68b17
1 changed files with 134 additions and 0 deletions
134
legacyworlds/doc/communications.txt
Normal file
134
legacyworlds/doc/communications.txt
Normal file
|
@ -0,0 +1,134 @@
|
|||
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.
|
Reference in a new issue