CLISER, the Client-Server Toolkit for RenderX XEP

Version 2

Abstract

CLISER allows to call XEP from any language with access to TCP sockets. A client application connects to XEP server by means of a simple protocol, sends an XSL Formatting Objects document and receives its formatted representation. Clients in several languages, including Perl, C, and Java, are provided.

Table of Contents

1. Rationale
2. Distribution
3. Protocol
3.1. Messages
3.2. Automata
3.2.1. Server-side
3.2.2. Client-Side
4. Server
5. Clients

1. Rationale

Originally, we introduced XEP CLISER to support SEEXEP, an on-line preview of a new (at that time) version of RenderX XEP. The web form was backed by a CGI script written in Perl, and we needed a way to call XEP from Perl. Launching Java for each request would mean high load and slow response (1 second at least to start JVM).

The obvious solution had been to start XEP once and to call it via an IPC channel; a solution based on TCP sockets had proved to be the simplest and the most straightforward one. It lets develop lightweight clients in various languages easily, and the server-side code is still simple enough to be stable. After the public launch, the service had run for several months almost unattended, and the load during first several weeks had been high enough to confirm the need for and feasibility of the solution.

A significant problem worth mentioning is the handling of images local to the client side. The protocol must have a means to pass them from the client to the server so that the server can render the images in the document. Among many ways to implement it, we chose to let the server query the client for client-local images it needs, and the client to send the images to the server over the same connection. Implemented in this manner, the protocol needs only a single communication channel, the server and the client are free to use their own file systems and run on different platforms, and relative images local to the client are handled transparently, with the source XSL FO document remaining intact.

2. Distribution

The distribution contains:

doc/

documentation describing the protocol and the implementations;

com/

Java source code;

Perl/, Python/, C/

client modules and command-line utilities in Perl, Python and C;

C/

C client module and command-line utility;

javadoc/

generated Java API documentation for Java classes;

cliser.jar

compiled java classes in a single Java archive file;

Makefile

Makefile to compile Java and C sources, suits both BSD and Gnu make utilities.

3. Protocol

The XEP CLISER protocol is connection-oriented; it uses plain-text commands; to send binary data, it first announces the length of the data to be sent. A single session allows to format multiple files and to change server options, such as the output format, as well as options for the formatter and an output generator. Failures caused by the environment (lost connection, file system error, protocol violation) will stop the session; but the server continues to process queries when a new session is established.

3.1. Messages

HELO version

Both sides send to introduce themselves to each other. The major number (digit before the dot) must be the same at both ends.

BYE message

Both sides send, requests shutdown of the peer.

OK message

Both sides send, confirms successful operation.

WARN message

Both sides send, a protocol-related warning.

ERR message

Both sides send, a protocol error.

LOG text

Server sends, XEP log entry.

SET key=value

Client sends, sets a server-side option.

SEND filename

Server sends, requests a file from the client.

RECV size string

Both sides send, announces data transfer, the string is either a system identifier or a format, depending on the context.

3.2. Automata

There are three automata, the main server, the file requester on the server, and the client. The tables below outline states and transitions for each of them. For convenience, the client automaton is split into parts.

3.2.1. Server-side

Table 1. Server

  HELO BYE SET RECV
Connected, send HELO. If versions match, send OK and go to Ready, otherwise, send BYE and go to Shutdown. Go to Shutdown.    
Ready   Go to Shutdown. Set server property, remain Ready. Receive source, send RECV on success, ERR on errors and remain Ready. Send BYE on fatal errors and go to Shutdown.

The following automaton comes into play when the server needs an external-graphic relative to a client-local document.

Table 2. getFile

  OK ERR RECV
Requesting, send SEND the file was sent earlier, go to Earlier. I/O error, go to Failed. receive the data, go to Received.

3.2.2. Client-Side

In the tables below, protocol commands are in upper case, API calls are in lower case letters.

Table 3. Handshake

  HELO BYE OK
Connected If versions match, send HELO, go to Introduced, otherwise, send BYE, go to Shutdown.    
Introduced   Go to Shutdown. Go to Ready.

Table 4. Ready to Render

  setprop render shutdown
Ready Send SET, remain Ready. Go to Render. Go to Shutdown.

Table 5. Rendering

  BYE OK WARN ERR LOG SEND RECV
Render, send RECV Go to Shutdown. Stay in Render. Report warning, stay in Render. Report error, go to Ready. Process log entry, stay in Render. Send RECV, OK or ERR, stay in Render. Receive formatted document, go to Ready.

4. Server

The server-side part of the protocol is implemented in com.renderx.xepx.cliser.Server. com.renderx.xepx.cliser.MTServer wraps a multi-threaded server around the core functionality, making it possible to concurrently serve multiple requests.

com.renderx.xepx.cliser.SampleEngine is a simple server launcher with command-line interface, once started it listens for incoming connections (the port is 6570 by default and can be changed by com.renderx.xepx.cliser.port java property or '-port' command-line switch) and launches server threads for each of them.

5. Clients

Clients in Java, C, Python, Perl and C# are provided with the distribution. The APIs are documented, javadoc in Java, Pod in Perl, Python documentation strings for Python. Client APIs are similar, but not identical; each implementation has been written in a way natural for the host language. We encourage the user to pursue the API descriptions and source codes of the clients.

Java

The implementation, along with a sample command-line interface. is in class com.renderx.xepx.cliser.Client. An application passes a connected socket to the constructor to create a client instance.

C

The client is in xec.h, xec.c; the sample command line utility is in xcc.c. The client can only handle one connection at a time, an application specifies server's host name and port number to initiate a session. to

Perl

The client is in package XEPX::CLISER::Client, the command-line driver is in xcc.pl. Plain Old Documentation, embedded into the source code of the client and explains the interface in detail. The constructor optionally expects server's host name and port number; the implementation uses IO::Socket to maintain the connection.

Python

The client is implemented as class xepx.cliser.Client, the command-line driver is in xcc.py. EnMasse, the XEP multiplexer, uses Python implementation of CLISER.

C#

The client is implemented as class Cliser.CliserClient, the command-line driver is CliserDriver.CliserDriver.

All clients can format multiple files and generate different output formats during a single session; they have been tested on a single computer and in a distributed environment.