1 Introduction

About Lichat-Serverlib

This is an implementation of the server-side protocol part of the Lichat protocol. It provides an extensible, transport-agnostic implementation that can be used to base a functional server on. All that the real server needs to take care of is the underlying connection establishment and reading.

You do not need this library if you are looking to implement a client. You don't need it if you're looking to implement a server either, but it will take care of a large part of the implementation tasks for you if you do use it.

Implementing an Overarching Server

In order to implement an actual server, you will want to do the following:

Subclass at least server and connection.

Provide functions to start a listener on a server instance.

For each client that connects, create a connection object.

Provide functions to repeatedly read updates from a connection and send them to process.

Supply an after method on teardown-connection that closes the connection to the client properly.

Provide a primary method for send specialised on your connection subclass that handles the actual wire transmission of an update.

Handle potential synchronisation or mutual-exclusion issues to users, channels, profiles, and connections on the server if your server is multi-threaded.

If the channel does not exist, a FAILURE-CONDITION for a
LICHAT-PROTOCOL:NO-SUCH-CHANNEL failure is signalled. If it
does exist, but the user is not a part of it, a FAILURE
CONDITION for a LICHAT-PROTOCOL:NOT-IN-CHANNEL failure is
signalled. Otherwise, the corresponding channel object is
returned.

This is in accordance with §5.1.5 §5.4.2 §5.4.3 §5.4.4 §5.4.5

See LICHAT-PROTOCOL:NO-SUCH-CHANNEL
See LICHAT-PROTOCOL:NOT-IN-CHANNEL
See FIND-CHANNEL

If the channel name is malformed, a FAILURE-CONDITION for
a LICHAT-PROTOCOL:BAD-NAME failure is signalled. If it is
valid, but a channel of that name already exists, a FAILURE-
CONDITION for a LICHAT-PROTOCOL:CHANNELNAME-TAKEN failure is
signalled.

This is in accordance with §5.1.3 §5.3.2

See LICHAT-PROTOCOL:BAD-NAME
See LICHAT-PROTOCOL:CHANNELNAME-TAKEN
See FIND-CHANNEL
See LICHAT-PROTOCOL:CHANNELNAME-P

Specifically, this will:
* Coerce the type-ish to a protocol type by looking the symbol
up in the lichat-protocol package.
* Add the :FROM initarg if it does not yet exist by using the
connection’s server’s name.

Creates an appropriate channel object for the registrant on the server.

If NAME is NIL, a random ID with an @ prefix is chosen
that does not already exist on the server.
If NAME is STRING= to the name of the server, a primary
channel is created.
Otherwise a regular channel is created.

This is in accordance to §2.4

Note that this will /not/ check whether a channel of the
given name already exists and will instead just replace
it.

See PREP-PERMS
See LICHAT-PROTOCOL:CREATE
See MAKE-CHANNEL
See FIND-CHANNEL
See LICHAT-PROTOCOL:*DEFAULT-ANONYMOUS-CHANNEL-PERMISSIONS*
See LICHAT-PROTOCOL:*DEFAULT-PRIMARY-CHANNEL-PERMISSIONS*
See LICHAT-PROTOCOL:*DEFAULT-REGULAR-CHANNEL-PERMISSIONS*

Sources that are accepted:
* STREAM – An update is read from the stream
and sent off to PROCESS again.
* LICHAT-PROTOCOL:UPDATE – The update is handled accordingly.

If an error of type FAILURE-CONDITION is signalled during the
evaluation of non-around methods, the encapsulated failure update
is sent to the connection. If an error of type LICHAT-PROTOCOL:
PROTOCOL-CONDITION is signalled during the evaluation of non-around
methods, an update of type LICHAT-PROTOCOL:FAILURE is sent to the
connection.

A CONTINUE restart is established around the method that can be
used to respond with a generic LICHAT-PROTOCOL:UPDATE-FAILURE
and return from the PROCESS method.

This method will also take care to handle flooding and timeout
recording for the connection.

The overarching server must establish a restart called CLOSE-
CONNECTION around the PROCESS method, or around all calls of it.
When this restart is invoked, the server must close the underlying
connection.

See LICHAT-PROTOCOL:FROM-WIRE
See LICHAT-PROTOCOL:PROTOCOL-CONDITION
See LICHAT-PROTOCOL:UPDATE-FAILURE
See FAILURE-CONDITION

Places that are accepted:
* CONNECTION – Directly sends the update over the wire. Note
that the primary method for this must be
implemented by the overarching server.
* USER – Relays the update to all connections of the user.
* CHANNEL – Relays the update to all users in the channel.

This function has to be called in a regular interval by the
overarching server. It will take care of handling connection
timeouts and will close the connection in case of one.