Over the last two days, I’ve been playing with multiplayer Flash applications using SmartFoxServer 2X. Having got the basic app up and running, the next step was to get events and requests (including data transfer) working between client and server. I spent a lot of time today reading over documentation, forums and apis, only to find there wasn’t a quick example of what I needed. So, for the benefit of the internets, here’s one I made earlier…!
Overview
In this example, we have part of an AS3 file used in our client application. The client attempts to connect to the SmartFoxServer 2X instance and join a room. Once we’ve joined the room (I’ve trimmed out all the necessary event listeners in the example, but they’re easy to work out), the server will send a response to the client with some data. On the client side, we’ll dispatch an event for the server to listen to, resulting in a message displayed in the SmartFoxServer console.
The Java Extension Classes
We’ll set up 3 java classes. One is the main extension class, the other two are our event/request handlers that are called as a result of server events or client requests. The key elements from the classes are blow:
Main Class: SimpleSmartFoxServerJavaExtension. This is the main extension class and is where we’ll set up our handlers.
package simple.test;
public class SimpleSmartFoxServerJavaExtension extends SFSExtension
{
@Override
public void init()
{
trace("Initialising SmartFox Extension example");
addRequestHandler("example_request", SimpleRequestHandler.class);
addEventHandler(SFSEventType.USER_JOIN_ROOM, UserJoinedRoomHandler.class);
}
@Override
public void destroy()
{
super.destroy();
removeRequestHandler("example_request");
removeEventHandler(SFSEventType.USER_JOIN_ROOM);
}
}
Example class to handle client requests
package simple.test;
@Instantiation(InstantiationMode.SINGLE_INSTANCE)
public class SimpleRequestHandler extends BaseClientRequestHandler
{
@Override
public void handleClientRequest(User arg0, ISFSObject arg1)
{
trace("We've just handled the example_request that was dispatched by the client");
}
}
Example class to handle server events
package simple.test;
public class UserJoinedRoomHandler extends BaseServerEventHandler
{
@Override
public void handleServerEvent(ISFSEvent arg0) throws SFSException
{
User user = (User)arg0.getParameter(SFSEventParam.USER);
trace("Event Received. User has joined the Room: " + user.getName());
//Same string as per SmartFoxClient's onExtensionResponse() function.
//Returns some mock data to the client
send("server_return_data", getReturnData(), user);
}
public ISFSObject getReturnData()
{
ISFSObject returnData = SFSObject.newInstance();
returnData.putInt("foo", 123);
return returnData;
}
}
So once we’ve got our basic java classes written, we’ll want to update our ActionScript 3 class to work correctly with these examples…
The AS3 Code
Here is the shortened (there’s no event listeners. You’ll need those!) code for working with events/requests. To save space in the example, I’ve bunched everything into the constructor with comments. Each step should have its own event listeners to check for successful completion before progressing.
public class SmartFoxClient
{
private var smartFoxServer : SmartFox;
public function SmartFoxClient()
{
smartFoxServer = new SmartFox();
//I'm not including the standard login etc events, just the one for listening
//for the example server extension responses.
//We're going to connect to a room. Once we've connected to the room ok, the server should
//dispatch an extension response via UserJoinedRoomHandler, which is caught in the
//onExtensionResponse() function below.
smartFoxServer.addEventListener(SFSEvent.EXTENSION_RESPONSE, onExtensionResponse);
//Connect to your server instance
smartFoxServer.connect("localhost", 9933);
//Once connected (use event listeners), we want to Login to a SmartFoxServer Zone:
smartFoxServer.send(new LoginRequest("MyUsername", "MyPassword", "Zone, e.g SimpleChat"));
//Once logged in to the zone (again, use event listeners), we can join a room:
smartFoxServer.send(new JoinRoomRequest("MyRoomName"));
//At this point, we have hopefully successfully joined the SmartFoxServer room, and now we'll
//test that the server can pick up our events and accompanying data object...
smartFoxServer.send(new ExtensionRequest("example_request", anISFSObject));
//You should see the trace message from SimpleRequestHandler output in your SmartFoxServer console.
}
public function onExtensionResponse(evt : SFSEvent) : void
{
trace("Got an expansion response");
var params : ISFSObject = evt.params.params;
var cmd : String = evt.params.cmd;
switch(cmd)
{
//Refer to the java UserJoinedRoomHandler class to see where
//this string is sent from
case "server_return_data":
trace("Returned value of params.foo: " + params.getInt("foo");
break;
}
}
…
Getting it Working
Once you’ve got your client and server code ready, the first thing you’ll need to do is wire up your extension via the SmartFoxServer Admin tool. To do this, you’ll need to follow these basic steps:
- Compile the java source into a jar file. You’ll end up with one file – we’ll call ours extensionExample.jar
- Copy this jar file into the “extensions” folder of your SmartFoxServer installation. For example, on my Mac’s local install, this would be something like: /Applications/SFS2X-RC1a/SFS2X/extensions/exampleExtension/exampleExtension.jar.
- Fire up your SmartFoxServer and access your admin client.
- Navigate to the “Zone Configurator” section and select the Zone that you chose to connect to in your AS3 code.
- Below the list of Zones are buttons to add/remove/edit them. Edit your chosen zone and proceed to the Zone Extensions tab.
- The two most important fields here are the Name and File ones. Name refers to the extension name. In this case, it would be set to “exampleExtension”. The File field is for the main class (including package name) of your extension jar. In the example here, it would be “simple.test.SimpleSmartFoxServerJavaExtension”. Once you’ve completed these fields, apply your changes.
- Now for the fun bit! Restart your SmartFoxServerInstance. If you follow the console logs, you should see your extension being initialised (if you kept the traces in). This is where you’ll also see any stacktraces, enabling you to patch up any issues.
- Fire up your Flash application and follow any steps required to test the communication. Make sure to keep an eye on the SmartFoxServer console as well as the flashlog. If all goes well, you’ll see the expected output! If not, don’t worry as the console should at least give you a good clue as to why not.
Issues I Encountered
One issue I found once the code was compiling ok was that there were other extensions trying to intercept my test events. They threw errors stating that that extension didn’t handle my custom events (obviously!). In my case, I was able to disable the other extension as it wasn’t needed. This stopped the error, but a better solution would need to be found in you were in need of multiple extensions.
Useful Links
And finally, here are some useful links to the 2X APIs and other documentation:
- SmartFoxServer 2X Main Page – with links to downloads, overviews etc
- SmartFoxServer 2X Docs – Links to all 2X documentation
- Admin Tool’s Zone Configurator documentation – Detailed overview of the Zone Configurator section mentioned in this post.
- AS3 API Docs
- Java Server Extesion API
Hopefully that’s of some use to someone! Apologies for any typos, this was thrown together while fighting off a cold!