8.18 Server side scheduler
One of the problems that usually game developers face while programming on the server side is how to handle multiple timed events and delays. A typical example is implementing count-downs for multiple bombs that should explode, or doors that should open or close etc...
Both Java and ActionScript offer a few solutions for handling time tasks (like the Timer class or setInterval) but none of them is really effective when you need to handle many of these events. Additionally both mentioned tools run on top of Java threads and each instance will take 1 thread, leading to a possible performance degradation if the number of timed tasks grows in the hundreds.
An example of this is when multiple threads are handling timed events in a Room-Level extension. Supposing we're using 4 threads for each room, you can imagine how many threads we would end up with once the number of Rooms grows. Even with only 100 rooms the JVM will have 400 threads to deal with, which can already tax the overall server performance.
» The solution
SmartFoxServer 1.6 provides a specific set of classes that will help in handling multiple time events using a global class called Scheduler, which can handle as many events as you wish by using one single thread.
Creating a new timed task requires the following steps:
» An example
The following is a simple ActionScript extension which demonstrates the usage of the Scheduler object.
The source of this example is provided with SmartFoxServer 1.6 in the sfsExtensions/ folder
// We import the correct java package
var _scheduler = Packages.it.gotoandplay.smartfoxserver.util.scheduling
// Global variable
var scheduler = null
function init()
{
trace(">>>>> Scheduler Test running ...")
scheduler = new _scheduler.Scheduler()
// Start the scheduler
scheduler.startService()
/*
* The Task object describes the task to be executed
* You can pass any object in the constructor, containing any custom parameters
*/
var task1 = new _scheduler.Task( {name:"have breakfast"} )
var task2 = new _scheduler.Task( {name:"play videogames"} )
var task3 = new _scheduler.Task( {name:"work a bit", start:"14:00", end:"17:00"} )
/*
* This is the object that handles the call-backs generated by the Scheduler
* when it's time to execute the task.
*
* The object must implement a method called doTask which receives a Task object
* as the argument.
*/
var handlerObj = {}
handlerObj.count = 0
handlerObj.doTask = function(task)
{
trace("Executing task: " + task.id.name)
if (task.id.name == "play videogames")
{
this.count++
trace("count = " + this.count)
if (this.count == 2)
{
task.active = false
trace("End of loop")
}
}
else if (task.id.name == "work a bit")
{
trace("Start at: " + task.id.start + ", End at: " + task.id.end)
}
}
// We create the call-back handler
var taskHandler = new _scheduler.ITaskHandler( handlerObj )
/*
* Here we add the tasks to the scheduler
* specifiying the delay interval (2nd param) in seconds
* if the task loops (3rd param)
* and the call-back handler (4th param)
*/
scheduler.addScheduledTask(task1, 3, false, taskHandler)
scheduler.addScheduledTask(task2, 5, true, taskHandler)
scheduler.addScheduledTask(task3, 4, false, taskHandler)
}
function destroy()
{
// This method should always be called to shut down the Scheduler
scheduler.destroy(null)
}
function handleRequest(cmd, params, user, fromRoom)
{
//
}
function handleInternalEvent(evt)
{
//
}
function handleInternalRequest( params )
{
//
}
While most of the code is self explanatory the portion of code where the callback handler is created requires a few comments. The handler should implement a Java interface, called ITaskHandler, which looks like this:
public interface ITaskHandler
{
public void doTask(Task task) throws Exception;
}
Even if you're not familiar with Java, "implementing an interface" simply means implementing the methods declared
by the interface, so in this case doTask().
In order to do this in ActionScript we simply create a generic object, attach a function to it called doTask(),
and finally pass the object while constructing a new ITaskHandler object.
For the complete documentation of the Scheduler classes please refer to the javadoc