The GT library is a groupware toolkit with two goals: to simplify the development of real-time distributed groupware, and to improve the performance of distributed applications. The toolkit makes it simple to build groupware by taking care of networking and by providing several high-level programming abstractions to deal with communication and distributed data. It is designed to speed the development of simple groupware applications by allowing developers to create distributed systems without the need to program lower-level networking code.
This distribution includes the GT source code, prebuilt binaries, and several demonstration programs. The demonstration clients rely upon a simple broadcasting server called the ClientRepeater; you must ensure a copy is started.
GT is made available under the GNU Lesser General Public License (LGPL) v2.1 or later. A copy of this license is included in the distribution as LICENSE.txt.
GT maintains a strong separation of clients and servers. Although peer-to-peer systems can be implemented by having a node maintain both a client and a server, this has not been GT's focus.
GT exports a notion of communicating across a set of typed channels. Channels are typed to simplify sending structured information, such as strings, bytes, objects, or session messages. There may be up to 255 different channels of each type. Each bit of structured information is sent across as a message.
GT is designed to be non-blocking and, ideally, single-threaded. Applications are required to periodically poll by calling the Update() method on their GT interface (e.g., Client.Update() or Server.Update()). Events are signalled through .NET events. Applications are responsible for implementing equivalent blocking semantics when required.
GT is structured as a three-level architecture. At the top level is the application level API, represented as instances of GT.Net.Client and GT.Net.Server. Clients and servers export different interfaces for handling messages. These interfaces are nominally connectionless. At the middle level are connexions and marshallers. Connexions serve as an aggregation of the different resources that can be used to communicate with a particular endpoint; connexions are represented as instances of IConnexion. Clients and servers use marshallers to convert messages into a form suitable to be communicated across a network; marshallers are represented as instances of GT.Net.IMarshaller. At the lowest level are transports which serve to communicate bundles of bytes to an endpoint using some network protocol; these transports are represented as instances of ITransport.
GT supports communicating across a variety of networking mechanisms, such as TCP and UDP. Applications can provide minimum delivery requirements for particular channels and for individual messages, such as whether a message must be sent across a networking mechanism with guaranteed delivery, or particular ordering requirements. These requirements are used to select a particular transport instance that meet those requirements.
Both clients and servers are built using a configuration object, GT.Net.ClientConfiguration for the client and GT.Net.ServerConfiguration for the server. Sample configurations are provided in GT.Net.DefaultClientConfiguration and GT.Net.DefaultServerConfiguration; these configurations are intended to serve only as examples and may change between releases. The examples should be copied and adapted for your particular application needs.
A client encapsulates the communication to different servers. Clients export a channel as a typed stream. We currently support 4 types of streams: strings (IStringStream), binary arrays (IBinaryStream), objects (IObjectStream), and session events (ISessionStream). GT also supports tuple streams, which provide automatically updating structures.
The main interface to GT Client is through instances of the GT.Net.Client class and the various stream instances.
Channels have quality-of-services requirements, described using a ChannelDeliveryRequirements object. These QoS requirements are used to find an appropriate transport able to meet those requirements. These QoS requirements may be overridden on a per-message basis using a MessageDeliveryRequirements object. Care must be taken for requirements specifying an aggregation level of MessageAggregation.Aggregatable: the user is responsible for periodically flushing the channel manually. These messages will be flushed by the periodic client/server ping, though this is usually scheduled to occur once every 10 seconds
Servers provide a more event-driven interface. As servers must scale to multiple clients, they are generally required to be more performant.
Marshallers have the responsibility of breaking object graphs into bytes, forms that can be transported across a network connection or written and read from disk. As multiple messages may be bundled together into a transport-level packet, a marshaller is responsible for placing message boundaries. This typically means that the marshaller should either write an explicit end-of-message indicator or tack a prefix to the content with a message length.
GT provides a standard object marshaller that uses the .NET Serialization. There are two variants of the marshaller. The first variant is a lightweight marshaller (LightweightDotNetSerializingMarshaller) that unmarshals only system-level messages, and leaves all application messages received as uninterpreted bytes; this is helpful for servers such as the ClientRepeater by avoiding any unnecessary latency by dropping all but the most basic functionality. The heavier-weight marshaller (DotNetSerializingMarshaller) uses the .NET serialization facilities.
We have also provided a proof-of-concept implementation of the general message compressor, an adaptively compressing marshaller that is well suited to marshalling data with repetitive structure between messages. This scheme is described in:
C Gutwin, C Fedak, M Watson, J Dyck, T Bell (2006). Improving network efficiency in real-time groupware with general message compression. In Proc of the Conf on Computer Supported Cooperative Work (CSCW), 119--128. (doi:10.1145/1180875.1180894, pdf)
Although GMC is fully functional, it is currently only supported across reliable and ordered transports.
GT Marshallers should never produce 0-byte messages. Marshallers should throw a GT.Net.MarshallingException exception on error.
Transports are responsible for carrying a set of bytes, called a Packet, to some remote endpoint. Transports describe their transportation characteristics which are used to match against a channel or message's required QoS requirements.
GT Transports should throw a GT.Net.TransportError when requested to send a 0-byte message.
GT uses both exceptions and an error event mechanism to communicate errors as they occur. There are several situations where errors may occur:
GT will raise exceptions on API violations or truly exceptional occurrences. Otherwise exceptions and errors are reported using the error event mechanism.
The exceptions currently defined are:
All GT exceptions and error events have an assessment as to their severity:
Errors/exceptions reported using the error event mechanism are notified using an ErrorSummary object. The ErrorSummary provides:
There are currently 5 different forms of a SummaryErrorCode which represent the implications of the error:
The Trac also hosts a list of Frequently Asked Questions.