Custom Room Storage
The Room Persistence API provide a file-based and a database-based storage mechanism that can be used to save the state of multiple active Rooms. However the API also allow to plug in custom storage systems as well.
In this short article we’ll demonstrate how to create a custom storage class to save Room state in your own format.
The basics
In our introductory article we show how to initialize the API in your Extension’s init() method:
It’s a simple one-line call to the Zone’s initRoomPersistence() method, where we provide the RoomStorageMode and relative configuration object.
RoomStorageMode provides the following options: - FILE_STORAGE - DB_STORAGE - CUSTOM
The latter allows us to use a custom implementation of the IRoomStorage interface.
Three simple steps
To get started with the development of a custom storage class we need three elements:
- an implementation of the IRoomStorage interface
- a configuration object extending BaseStorageConfig
- one line in the Extension’s main init() method to set it all up
Implementing IRoomStorage
The interface looks like this:
void destroy()
void init(Zone zone, BaseStorageConfig cfg)
void saveRoom(Room theRoom) throws SFSStorageException
void saveAllRooms() throws SFSStorageException
void saveAllRooms(String groupId) throws SFSStorageException
CreateRoomSettings loadRoom(String name) throws SFSStorageException
List<CreateRoomSettings> loadAllRooms() throws SFSStorageException
List<CreateRoomSettings> loadAllRooms(String groupId) throws SFSStorageException
void removeRoom(String name) throws SFSStorageException
void removeAllRooms() throws SFSStorageException
void removeAllRooms(String groupId) throws SFSStorageException
Essentially there are an init() and destroy() method that manage the life cycle of the object, allowing to create and dispose of useful resources. Then we have the load, save and remove methods each with three variants, depending if we're dealing with a single Room, a selection of Rooms or all the Rooms.
Create a configuration object
Next we need a configuration object that can be populated with settings for our Storage logic. For instance if we were to read and write from a database we’d need a connection string to reach the DB server and probably a database name and table name.
The base class for our configuration object is called BaseStorageConfig and comes pre-populated with a few global settings:
Continuing with the example of a DB-based storage here’s how one could extend the class:
Please Note
Keep in mind that your custom Storage logic should honor the settings contained in the base class. In other words it should check the values of the base class’ flags and filter out the relative data accordingly.
Putting it all together
In order for SmartFoxServer to load the custom classes they will need to be visible in the system Class Loader. To do so we'll need to make a jar file of the custom Storage classes and deploy it under server/lib/extra/
Next we move in our Extension and initialize the Room Persistence API as follows:
public class CustomRoomStorageExtension extends SFSExtension
{
@Override
public void init()
{
MyDBStorageConfig config = new MyDBStorageConfig();
config.param1 = ...
config.paramX = ...
config.customStorageClassName = "my.sfs3.game.MyRoomStorage";
getParentZone().initRoomPersistence(RoomStorageMode.CUSTOM, config);
}
}
Notice the customStorageClassName property: we must provide the fully qualified name of the IRoomStorage implementation.
A complete example
To help you build a custom Room Storage class we have included the source code for our file-based Room Storage so you can look at an existing implementation.