SFS2X Docs / DevelopmentBasics / server-variables
» Server Variables
The SmartFoxServer 2X framework provides different types of Server Variables that can be used to maintain synchronized state across users, Rooms and buddies inside a Buddy List.
Server Variables, in general, allow the client or server logic to create custom values that are automatically updated within their scope. There are three main types of Server Variables with different scope:
- User Variables: they represent custom data attached to a single user. All updates are received by the users in the same Room(s) where the owner is joined. In other words a user called Piggy will be able to access and get updated about all Variables of user Kermit when they are both joined in the same Room. A common use case is to store custom User profile or game data (score, rank, age, interests, avatar, game achievements, etc).
- Room Variables: they represent custom data attached to a Room object. Their scope is the Room itself so users will be able to access Room Variables once they have joined a specific Room. There are also ways to make these variables visible and receive updates from outside the Room. A common use case is to keep the state and properties of a game (skill level, score, best score, current game state, etc).
- Buddy Variables: they represent custom data attached to a buddy inside one or more Buddy Lists. The scope is the Buddy List itself, so anyone who has added a user called Gonzo in their list will see and receive updates for his Variables. The most useful application is to keep every friend updated about one's own status in real-time.
» General architecture
The following diagram illustrates a simplified hierarchy of the different types of server variables. At the top we have the Variable interface defining the basic properties such as name and value. Below we find different sub-classes that extend the basic features and add new properties such as private, persistent, etc.
Let's take a more in depth look at each property:
- name: can be any valid string but keep in mind that short names will use less bytes and therefore less bandwidth. Often times 2-5 characters are enough to define your variables.
- value: all Server Variables support several basic types:
- Null (used only to delete a variable)
- Boolean
- Integer (signed 32 bit)
- Double (64 bit double)
- String (up to 32768 characters)
- SFSObject
- SFSArray
- isHidden: by default all variables are not hidden. You can turn on this flag for User and Room Variables to keep these values only on the server side. Clients will never receive any updates about hidden variables. This flag is available only on the server side.
- isPrivate: this flag has different effects when activated on a User Variable or Room Variable. Private User Variables are accessible only to their respective owners. Private Room Variables are visible to all clients in the Room but can only be modified by the owner.
- isPersistent: by default a user created Room Variable is removed from the Room when the user leaves it. If this flag is turned on, the Room Variable will persist until the user logs out or disconnects (default=false).
- isGlobal: a global Room Variable is visible from outside the Room. This means that any user will be able to access it and receive updates even if he's not joined the Room. Running too many global Variables can use significant bandwidth in a high traffic server. Use with moderation (default == false).
- isStorable: (since 2.14) specifies wether or not a variable should be stored by a persistence service such as the Room Persistence API, which allows to store Room definitions and variables to a file or database (default == true).
Static Room Variables
While User Variables and Buddy Variables can only be created dynamically via code, Room Variables can also be created statically at configuration time. You can learn more about this by consulting the documentation about the AdminTool's Zone Configurator.
» Examples of usage
Below you will find a few examples of how to use Room and User Variables from the client API (sfs is the SmartFox class instance). Buddy Variables will be treated separately in the largest context of the Buddy List API.
User Variables
The following example shows how a user can store his profile using Variables and automatically update all other clients in the same Room(s):
// Create a list of User Variables List<UserVariable> listOfVars = new List<UserVariable>(); // Add a few User Variables listOfVars.Add(new SFSUserVariable("avt", "MissPiggy.png")); listOfVars.Add(new SFSUserVariable("occ", "Acting and singing")); listOfVars.Add(new SFSUserVariable("loc", "Muppet's Show")); // Send the request to set Room Variables sfs.Send(new Sfs2X.Requests.SetUserVariablesRequest(listOfVars));
// Set a few User Variables var avatarPic = new SFS2X.SFSUserVariable("avt", "MissPiggy.png"); var occupation = new SFS2X.SFSUserVariable("occ", "Acting and singing"); var location = new SFS2X.SFSUserVariable("loc", "Muppet's Show"); // Send the request to set User Variables sfs.send(new SFS2X.SetUserVariablesRequest([avatarPics, occupation, location]));
// Set a few User Variables var avatarPic:UserVariable = new SFSUserVariable("avt", "MissPiggy.png"); var occupation:UserVariable = new SFSUserVariable("occ", "Acting and singing"); var location:UserVariable = new SFSUserVariable("loc", "Muppet's Show"); // Send the request to set User Variables sfs.send(new SetUserVariablesRequest([avatarPics, occupation, location]));
To receive the update, clients must be listening to the SFSEvent.USER_VARIABLES_UPDATE event and handle it like thi:
... // Add variable-related event listener during the SmartFox instance setup sfs.AddEventListener(SFSEvent.USER_VARIABLES_UPDATE, OnUserVarsUpdate); ...
private void OnUserVarsUpdate(BaseEvent evt) { // Get the user that changed his variables User user = (User)evt.Params["user"]; // Do something with the values Console.WriteLine("Location: " + user.GetVariable("loc").GetStringValue()); Console.WriteLine("Occupation: " + user.GetVariable("occ").GetStringValue()); }
... // Add variable-related event listener during the SmartFox instance setup sfs.addEventListener(SFS2X.SFSEvent.USER_VARIABLES_UPDATE, onUserVarsUpdate, this); ...
function onUserVarsUpdate(evt) { // Get the user that changed his variables var user = evt.user; // Do something with the values console.log("Location: " + user.getVariable("loc").value); console.log("Occupation: " + user.getVariable("occ").value); ... }
... // Add variable-related event listener during the SmartFox instance setup sfs.addEventListener(SFSEvent.USER_VARIABLES_UPDATE, onUserVarsUpdate); ...
private function onUserVarsUpdate(evt:SFSEvent):void { // Get the user that changed his variables var user:User = evt.params.user as User; // Do something with the values trace("Location: " + user.getVariable("loc").getValue()); trace("Occupation: " + user.getVariable("occ").getValue()); ... }
Room Variables
The following is a quick example of how to set a private Room Variable from client side:
// Create a list of Room Variables List<UserVariable> listOfVars = new List<UserVariable>(); // Add a Room Variable listOfVars.Add(new SFSUserVariable("topic", "Multiplayer Game Development")); // Send the request to set Room Variables sfs.Send(new Sfs2X.Requests.SetRoomVariablesRequest(listOfVars));
// Set a Room Variable var chatRoomTopic = new SFS2X.SFSRoomVariable("topic", "Multiplayer Game Development"); // Send the request to set Room Variables sfs.send(new SFS2X.SetRoomVariablesRequest([chatRoomTopic]));
// Set a Room Variable var chatRoomTopic:RoomVariable = new SFSRoomVariable("topic", "Multiplayer Game Development"); // Send the request to set Room Variables sfs.send(new SetRoomVariablesRequest([chatRoomTopic]));
To receive the update, clients must be listening to the SFSEvent.ROOM_VARIABLES_UPDATE event and handle it like this:
... // Add variable-related event listener during the SmartFox instance setup sfs.AddEventListener(SFSEvent.ROOM_VARIABLES_UPDATE, OnRoomVarsUpdate); ...
private void OnRoomVarsUpdate(BaseEvent evt) { // Get the names of variables that were updated for the Room List<String> changedVars = (List<String>)evt.Params["changedVars"]; // Obtain the variable and do something with it if (changedVars.Contains("topic")) { RoomVariable topicRV = sfs.LastJoinedRoom.GetVariable("topic")); Console.WriteLine("The room topic is now set to: " + topicRV.GetStringValue()) } }
... // Add variable-related event listener during the SmartFox instance setup sfs.addEventListener(SFS2X.SFSEvent.ROOM_VARIABLES_UPDATE, onRoomVarsUpdate, this); ...
function onRoomVarsUpdate(evt) { // Get the names of variables that were updated for the Room var changedVars = evt.changedVars; // Obtain the variable and do something with it if (changedVars.includes("topic")) { var topicRV = sfs.lastJoinedRoom.getVariable("topic"); console.log("The room topic is now set to: " + topicRV.value); } }
... // Add variable-related event listener during the SmartFox instance setup sfs.addEventListener(SFSEvent.ROOM_VARIABLES_UPDATE, onRoomVarsUpdate); ...
private function onRoomVarsUpdate(evt:SFSEvent):void { // Get the names of variables that were updated for the Room var changedVars:Array = evt.params.changedVars as Array; // Obtain the variable and do something with it if (changedVars.indexOf("topic") >= 0) { var topicRV:RoomVariable = sfs.lastJoinedRoom.getVariable("topic"); trace("The room topic is now set to: " + topicRV.getValue()); } }
» Variables on the server-side
Using Variables on the server side is equally straightforward and uses the same interface and logic. Even if you still have to learn how to develop your own custom server side Extensions (see the Extensions Development sections), here you will find a couple of examples showing the principles of working with User and Room Variables in a Java Extension.
User Variables
Let's set a couple of User Variables. One of them will be exclusively server side, using the hidden property.
private void setUserProfile(User user, int databaseId) { // Define a public User Variable UserVariable avatarPic = new SFSUserVariable("pic", "GonzoTheGreat.jpg"); // Define a private User Variable UserVariable dbId = new SFSUserVariable("dbId", databaseId); dbId.setHidden(true); // Set User Variables via the server side API getApi().setUserVariables(user, Arrays.asList(avatarPic, dbId)); }
Room Variables
Let's take a look at Room Variables now. The interesting thing about creating them on the server side is that their "creator" will be the server itself. Just like from client side the creator is the user who sends the request.
This means that server-created Room Variables will never expire, in contrast to those generated with the client API. This can be used to maintain fully persistent values in any Room that requires it.
private void setupRoomVariables(Room room) { // Define a private, global Room Variable; no one will be able to overwrite this value // Being a global Variable, its value will be visible from outside the Room RoomVariable chatTopic = new SFSRoomVariable("topic", "Multiplayer Game Development"); chatTopic.setPrivate(true); chatTopic.setGlobal(true); // Define an hidden Room Variable, only accessible from server side RoomVariable isModerated = new SFSRoomVariable("isMod", true); isModerated.setHidden(true); // Set Room Variables via the server side API // Passing null as the User parameter sets the ownership of the variables to the Server itself getApi().setRoomVariables(null, room, Arrays.asList(chatTopic, isModerated)); }
» Learning more
In order to learn more about Server Variables we recommend to check the specific server and client side API for your platform of choice. You find all the links on the left side menu under the Client and Server API Documentation sections.