6.8 Python Extension
Since SmartFoxServer 1.5.0 we've added support for Python as a scripting language for developing server side extensions.
Python is a highly productive, fully object oriented language that allows rapid prototyping and development of server extension. Thanks to the Java implementation of Python (often referred to as Jython) it is also possible to access the entire Java framework, making it an extremely flexible tool.
The current Python implementation supports the Python 2.2 language specifications.
» Quickstart
If you are familiar with server side Actionscript extensions you will have very little to learn: Python extensions use the same logic and work in the same exact way of AS extensions. The following is the simplest Python extension possible:
#
# SmartFoxServer PRO
# Pyhton Extension template
# version 1.0.0
#
def init():
_server.trace("Python extension starting")
def destroy():
_server.trace("Python extension stopping")
def handleRequest(cmd, params, who, roomId, protocol):
pass
def handleInternalEvent(evt):
pass
As you can see we have the usual 4 methods: init(), destroy(), handleRequest() and handleInternalEvent()
The _server variable is a globally scoped object that allows to access the server side framework, just like in Actionscript and you will be able to invoke the same methods.
NOTE: Starting from SmartFoxServer 1.6 a new optional method is made available to the extensions, called handleInternalRequest. The method allows cross-extension calls and other interesting features. All the details are explained at Chapter 6.11.In order to learn more about the _server object methods you can consult the Python server API.
» Differences between Python and Actionscript
The most significant difference between Python and Actionscript extensions is how internal server events are handled.
While in Actionscript you receive a native object populated with the event properties, in Python you will
receive the same object you would receive in a Java extension. In other words the event object is a java class, specifically the received object is an instance of it.gotoandplay.smartfoxserver.events.InternalEventObject
This class has 3 methods:
| name | returns | returned type | |
| getEventName() | returns the event name | string | |
| getParam(paramName) | gets a string parameter from the event object | string | |
| getObject(paramName) | gets an object parameter from the event object | object |
Here's a list of the internal events dispatched by the Server and the parameters passed:
loginRequest
userJoin
userExit
userLost
newRoom
roomLost
spectatorSwitched
pubMsg
privMsg
fileUpload
The following is an example of how you should handle a userJoin event:
def handleInternalEvent(evt):
evtName = evt.getEventName()
if evtName == "userJoin":
zone = evt.getParam("zone")
room = evt.getObject("room")
user = evt.getObject("user")
# Let's take advantage of python way of formatting strings
message = "User %s joined room %s in zone %s" % (user.getName(), room.getName(), zone)
_server.trace(message)
Notice that we user getParam() to obtain string parameters and getObject() for any other parameters passed in the event object.
» Python examples
With SmartFoxServer 1.5 we provide a few examples of Python extensions that you can inspect to learn more about its usage. You will find them in the Server/sfsExtensions/ folder in your SmartFoxServer installation directory:
| ExtensionTemplate.py | A simple extension template | |
| dbExtension.py | The Python version of dbExtension.as (see tutorial 8.3) | |
| mazeGame.py | The Python version of mazeGame.as (see tutorial 8.6) |
» Importing modules
We recommend creating your Python modules under the sfsExtensions/ folder or any other nested directory under that path.
If you get an error when loading your custom modules you should add the following code to your init() method, in order to set the sys.path property correctly:
import sys, os
importPath = os.path.abspath("sfsExtensions/")
if not (importPath in sys.path):
sys.path.append(importPath)
# from here you can import your custom modules...
import MyCustomModule
def init():
# ... your code here ...
pass
When reloading a Python extension only your main extension file will be actually reloaded, so if you have done changes to your modules you won't
be able to see them, unless you restart the server.
You can easily avoid this problem and reload all the modules by simply removing them from the sys.modules property in the destroy() method.
The following code shows how:
def destroy(): del sys.modules["MyCustomModule"] del sys.modules["MyOtherModule.SubModule"] # etc...
| doc index |