Rakkarsoft LLC

System Overview
System Architecture

RakPeer.h provides the base functionality for all of RakNet.  On start, RakPeer starts a thread that will process all incoming datagrams and send most outgoing datagrams.  A shared memory array of RemoteSystem structures is shared between the user thread and the network thread.  Messages are sent between these two threads using a fast single producer single consumer object.  Each player has one entry in the array of RemoteSystem structures.  Each element in the array has an instance of the ReliabilityLayer class, which handles reliable sends, ordering, and integrates with the message security classes.  As user messages arrive, they are stored a single producer single consumer queue.  When a user wants a message, by calling Receive(), this will return a pointer to one element of the queue.  When a user is done with a message, by calling DeallocatePacket(), this will increment the write pointer of the queue.  This is why you have to return messages in the same order as you get them.

Calling Receive() also does any user-thread based processing.  One case of this is RakNet's plugin system.  The plugin system is just an interface (PluginInterface.h) that has hooks inside RakPeer to perform certain functionality on certain events.  The biggest two are Update() and the processing of packets in OnReceive(), both of which happen when the user calls RakPeer::Receive().  This has two advantages.  First, you don't have to keep track of which plugin modules you are using.  Second, if a plugin module has its own message types, those message types can be processed in the plugin and blocked from being returned from Receive().  Hence, your application can add modular functionality with no code changes beyond adding the plugin itself.

RakNet's messaging system works by treating the first byte of any message as an identifier indicating the format and meaning of the rest of the data in the message.  The message id bytes used by RakNet are stored in the file PacketEnumerations.h.  Users that want to extend this system can start their own enumerations starting at the highest enumeration in PacketEnumerations.h + 1.  Users would then check the first byte of messages that are returned to them and call a function to handle the rest of the data in the message.  To make this easier, RakNet supports remote function calls.  Essentially, remote function calls perform this mapping for you by registering a string with a function pointer.  You then call RakPeer::RPC with the name of the function and if the other side has that function registered, it will call the function pointer along with a structure containing data such as encoded parameters and who sent the message.  This system has two further extensions.  First, it supports return values by blocking in the Receive() call until a message is returned or until a timeout elapses.  Second, it supports calling into object member functions, not just static C functions.

The NetworkIDGenerator class provides the ability for systems to refer to common objects and is used by object member remote function calls.  It is a fairly simple system that has the server assign a number to objects as they are created.  When a client creates an object, it is responsible for sending this event to the server, getting the number to use when the object is created on the server in turn, and then assigning this number to the object.  This way systems can refer to objects on multiple systems which would otherwise be impossible since pointer addresses would probably not be the same.  The easiest way to use this system is to derive from it.  However, you can also include it as a member variable of your base class and call SetParent(parentClassPointer).  The disadvantage of this architecture is that it relies on a single system being present to assign network IDs.  This can be addressed by having NetworkIDs be a PlayerID / NetworkID pair instead of a simple number.  However, that takes more bandwidth which would be wasted in server/client topology, which happens to be the most common case.  It is currently implemented using a single number.

The PlayerID structure is what RakNet uses to represent remote systems.  It is the binary encoding of the IP address along with the port of that system.

The BitStream class, located in BitStream.h, is natively supported by RakNet.  This is both a user class and an internal class.  It is primarily used to write single bits to a stream and for automatic endian swapping, which can be enabled by commenting out  __BITSTREAM_NATIVE_END in BitStream.h.  It is disabled by default for speed, since most users do not need endian swapping.


User classes / files

These are the classes and files designed to be used by the user.  All other classes and files are internal, or are in support of these classes.  All user classes are extensively documented in the header file so you should look there for function level documentation.  In every case you can find the class inside the header file of the same name.

Bitstream - Used to write bits to a stream.  If you are sending between systems with different endian representations you should use this for all your data to do automatic endian swapping.  Also supports compression for certain types such as quaternions and vectors.

CommandParserInterface - An interface you can derive from to add more command string parsing capabilities to ConsoleServer.

ConsoleServer - Allows you to remotely log into your game and send command line directives.  You choose a transport provider for the data and add one or more command parsers derived from CommandParserInterface.  Built-in transport providers include RakNetTransport (secure) and TelnetTransport (insecure but all computers have telnet built in).

FullyConnectedMesh - A implementation of PluginInterface that will watch for connection packets and automatically connect your system to all other systems in the mesh.

GetTime - Returns the system time in milliseconds.  This is the number system RakPeer uses for timestamping packets.

LogCommandParser - An implementation of CommandParserInterface  that allows remote systems to request channel based log output to the console window.  Used for remote log output. See the CommandConsoleServer example to see this in practice.

Multiplayer - Depreciated.  Parses all the internal RakNet messages and calls a corresponding function from a switch / case statement.  You should just write your own switch / case.

NetworkIDGenerator - Assigns a number to an object in that object's constructor if the local system is the server.  Otherwise lets you set this number manually.  Used to refer to the same instance of the same object across multiple systems.

PacketConsoleLogger - A derivation of PacketLogger that writes to the LogCommandParser instead of the screen.

PacketEnumerations.h - All the packet enumerations returned by RakNet in the first byte of messages.  This includes disconnect and connect messages.

PacketFileLogger - A derivation of PacketLogger that writes to a file instead of the screen.

PacketLogger - An implementation of PluginInterface that tracks at a low level all the packets that go in and out of RakNet and writes them to the screen.

PluginInterface - RakNet's plugin system.  You can derive from this to write your own plugins.

RakClientInterface - Depreciated though in widespread use.  A specialization of RakPeer.  This is here because the first version of RakNet was client / server only rather than peer to peer.

RakNetCommandParser - The interface you can derive from to add your own custom command parsing to ConsoleServer.  It's very easy to use - look at LogCommandParser for an example of a parser that comes with RakNet.

RakNetStatistics - RakPeer::GetStatistics returns this structure.  Returns a large number of statistics related to network activity.

RakNetTransport - One of the transport methods used by ConsoleServer.  Secure.  If you use this transport provider you will need to connect to ConsoleServer using the code in the sample CommandConsoleClient.

RakNetworkFactory - A factory class to new and delete user classes.  Only necessary if you use the DLL since DLL classes have to be new'ed and deleted inside the DLL that contains them.

RakPeerInterface - Provides core library functions such as sending and receiving messages, pinging, statistics, player management, security, and more.

RakServerInterface - Depreciated through in widespread use.  A specialization of RakPeer.  This is here because the first version of RakNet was client / server only rather than peer to peer.

Rand.h - C function prototypes to return random numbers.  Use it if you want.

ReplicaManager - A management system for your game objects and players to make serialization, scoping, and object creation and destruction easier.

SimpleMutex - A simple Lock / Unlock mutex class based on critical section objects.  You can use it if you are doing multithreaded programming but it is optional.

StringCompressor - Encodes / decodes strings using Huffman compression.  If you are sending English language strings you can reduce bandwidth this way.

TelnetTransport - One of the transport methods used by ConsoleServer.  Insecure, but every computer comes with Telnet.

TransportInterface - Derive from this to write your own string based transport providers for ConsoleServer.


Next page: Detailed Implementation

See Also
Index
Introduction
Detailed Implementation
Tutorial
Compiler Setup