• Examples (iOS)
• Examples (Java/Android)
• Examples (C++)
Server API Documentation

 

Since 2.8.0

» Room Persistence API

In SmartFoxServer 2X 2.8.0 we have introduced a new Room Persistence API to help store and retrive the state of Rooms. This feature can be particularly useful to store the state of a ongoing games, personal Rooms in virtual worlds and more.

» Overview

The Room Persistence API is outlined in the basic IRoomStorage interface provided under the com.smartfoxserver.v2.persistence.room package:

IRoomStorage:

Each group of methods allow to work with a specific Room, a group of Rooms or the entire Room list inside the Zone. Rooms are stored by serializing all their properties (the CreateRoomSettings object) and, optionally, all their Room Variables.

NOTE: when storing Room Variables remember that only server-owned variables will be persisted. This is because variables owned by Users cannot be recreated at a later time without the presence of that Variable's owner in the Room.

» Implementations

We provide two different implementations out of the box:

» Quick start

Each Server Zone runs a different instance of the Persistence API, so we can customize the persistence settings for each Application independently.

The following code shows how to initialize the Room Persistence API in our Zone Extension:

	// Init method of a Zone Extension 
	public void init()
	{
		// Initialize Persistence API
		getParentZone().initRoomPersistence(RoomStorageMode.FILE_STORAGE, new FileRoomStorageConfig());
	
		// Load all previously stored Rooms
		try
		{
			List<CreateRoomSettings> allRooms = getParentZone().getRoomPersistenceApi().loadAllRooms();
	        
	        // Recreate all Rooms
	        for (CreateRoomSettings settings : allRooms)
	        {
	        	getApi().createRoom(getParentZone(), settings, null, false, null, false, false);
	        }
		}
		catch (SFSStorageException storageErr)
		{
			trace("Error loading rooms: " + storageErr);
		}
	    catch (SFSCreateRoomException creationErr)
	    {
	    	trace("Error creating room: "  + creationErr);
	    }
	}

We initialize the API by providing a Room Storage Mode (either FILE_STORAGE or DB_STORAGE) and the relative instance of the configuration class (FileRoomStorageConfig, DBRoomStorageConfig). Then we proceed with loading all the previously stored Rooms and re-create them in the system using the SFSApi.createRoom(...) method.

When initializing the RoomPersistence API you may also want to configure a number of settings:

NOTE: static Rooms are those defined in the Admin Tool > Zone Configurator. These Rooms are already re-created every time the Server boots up. If you store them via the Persistence API and then attempt to re-create them, you will get an error because those Rooms already exist. Normally you don't need to persist static Rooms.

Each persistence implementation provides also a number of custom settings, for example the database-driven implementation allows to specify the table name, a custom DBManager etc... You can read all the details in the Server Side API javadoc, under the com.smartfoxserver.v2.persistence.room package.

ยป Database persistence example

	// Init method of a Zone Extension 
	public void init()
	{
		DBRoomStorageConfig cfg = new DBRoomStorageConfig();
		cfg.tableName = "my_game_room_data"

		// Initialize Persistence API
		getParentZone().initRoomPersistence(RoomStorageMode.DB_STORAGE, cfg);

		// Load all previously stored Rooms
		try
		{
			List<CreateRoomSettings> allRooms = getParentZone().getRoomPersistenceApi().loadAllRooms();
	        
	        // Recreate all Rooms
	        for (CreateRoomSettings settings : allRooms)
	        {
	        	getApi().createRoom(getParentZone(), settings, null, false, null, false, false);
	        }
		}
		catch (SFSStorageException storageErr)
		{
			trace("Error loading rooms: " + storageErr);
		}
	    catch (SFSCreateRoomException creationErr)
	    {
	    	trace("Error creating room: "  + creationErr);
	    }
	}

The only difference with the file-based example is the use of DBRoomStorageConfig to configure tha API. Here we need to define at least the table name we want to use for the storage. As regards the database connection details, the API will use the Zone's Database Manager which is configured from the AdminTool's Zone Configurator.

If you prefer to define a separate connection for the API persistence you can also do so by specifying it in the DBRoomStorageConfig object:

	public void init()
	{
		DBConfig cfg = new DBConfig();
		cfg.active = true;
        cfg.driverName = "com.mysql.jdbc.Driver";
        cfg.connectionString = "jdbc:mysql://127.0.0.1/database_name";
        cfg.userName = "db_user_name";
        cfg.password = "db_user_pass";
        cfg.testSql = "SELECT name FROM some_table LIMIT 1"; 

		DBRoomStorageConfig cfg = new DBRoomStorageConfig();
		cfg.tableName = "my_game_room_data"
		cfg.dbManager = new SFSDBManager(cfg);

	}

» Suggested use

Below we discuss two different use cases for the Room Persistence API and provide some tips on how to obtain the best performance.

» Save and load the game state for long running matches

The first case scenario is a game of chess where the match could last for days, weeks or even months. Opponents will be able to connect to the server and restore the game from where they left it since the last move. In order to accomplish this we will need:

With this in mind we should be able to easily implement a game that allows players to freeze the match and return another time to continue from where they left.

Creating a unique Room name can be tackled in many different ways. The simplest ideas is to identify the Room after the two opponents' names. Since all user names are unique inside a Zone, combining two unique names will give us a unique Room name for each game. For example we could use a convention such as <Player1>_vs_<Player2> for the Room name.

Next we need a way for players to tell the system that they want to suspend the game. This can be done in several ways:

In order to restore the game when the User comes back there are also multiple options. The best idea is to store the ongoing game Room names in the User profile itself, so that when the player logs in again the system can immediately recreate the suspended game.

» Save and load the Room state for personal Rooms.

One common feature of online virtual worlds is to provide each User with a custom "home" that they can customize and configure with all sorts of decorations and personal items.

Using the Room Persistence API can be the easiest way to save and load on demand these Rooms when players become active in the system. The basic requirements for this functionality are very similar to the previous use case:

We can again leverage the uniqueness of the User's name to create a distinctive personal Room name. Something as simple as Home_<PlayerName> will do the trick. Next we need to create the Room Variables that will keep track of the various User's decorations.

If the number of customizations is very high (let's say more than 30 parameters) we can leverage the convenience of SFSObjects instead of using one RoomVariable-per-setting approach. For example we can compact all settings for the Room's furniture in one SFSObject and all personal details in another SFSObjects etc... and finally store these SFSObjects as Room Variables.

In order to store and retrieve these personal Rooms on demand we can simply rely on the user login and disconnection events. Each time the client joins the system we can load his/her personal Room data and create the Room in the system. Similarly when the user leaves the system by disconnecting we can store the Room and get rid of it until the next login.

» Excluding specific Room variables

Since SFS2X 2.14 RoomVariables expose a new flag called storable that can be used to selectively exclude specific Variables from being saved by the Room Persistence API.

The flag is set to true by default in every RoomVariable, but you can turn it off at creation time to signal which Variables should be skipped by the Persistence API.

Example:

	RoomVariable rv = new SFSRoomVariable("TempName", "Sir No Name");
	rv.setStorable(false);

» Custom Room Storage with SFS2X 2.18

Since the release of SmartFoxServer 2X 2.18.0 we have introduced a way to override the default implementations for the Room Persistence API so that they can be customized to your needs.

You can read all the details in this article.