6.11 Extension Interoperability
SmartFoxServer 1.6 introduces a new simple and effective way to make server side extensions more interoperable between them and from other objects.
A new method called handleInternalRequest is now part of the Extension interface:
public Object handleInternalRequest(Object object)
{
// Can be any type
Object someObject;
/*
* ...
* body of the method
* ...
*/
return someObject;
}
With this new optional method each extension is now capable of receiving method calls from any object, be it another extension, a servlet running in the embedded webserver, another object, etc...
Additionally the same method exists for Actionscript and Python extensions making it possible to implement cross-communication between Extensions written in different languages and even running in different Zones.
Here's a snippet of Java code that demonstrates how an extension can perform a request to another running extension:
// Get a reference to the Zone where the target extension is running
Zone zone = SmartFoxServer.getInstance().getZone("testZone");
// Get a reference to the Extension we want to call
AbstractExtension targetExtension = zone.getExtension("testExtension");
// Invoke the handleInternalRequest on the target extension and receive the response
String response = (String) targetExtension.handleInternalRequest("Hello");
trace("Response: " + response);
And this is what the target extension handleInternalRequest method could look like:
public Object handleInternalRequest(Object object)
{
String message = (String) object;
if (message.equals("Hello"))
{
return "Hello to you!"
}
else
{
return "Unrecognized message."
}
}
» Extension monitoring and debugging
Another important aspect of the new interoperability feature is the ability to easily create custom debuggers and admin tools for your extensions. For example you can quickly create a remote debugger by running a dynamic web-page in the embedded web-server which in turn sends commands to your extension(s) and outputs its responses.
» Using different server languages
Since SmartFoxServer supports multiple languages on the server side it may become a little complicated to pass objects to and from extensions written in different languages. In order to reduce type-compatibility problems we suggest to always use Java types as arguments and return types, when invoking the handleInternalRequest() method.
For example, if you wish to send a list of strings from an Actionscript extension to a Java extension, you should use a Java ArrayList or LinkedList
instead of a native Actionscript array.
Similarly you should return a Java type from the target extension which can be easily handled by the calling Actionscript code.
NOTE: There is one particular case in which you should pay attention at how Objects are passed via the handleInternalRequest() method.
The "special case" is when returning Java objects from an Actionscript extension.
In this case the Java object is "wrapped" in a special object and would cause a java ClassCastException if you try to cast it to the expected type.
Luckily the "wrapping" object exposes an unwrap() method which allows to retrieve the original object and finally cast it to the wanted type.
A code example will probably help understanding. Suppose we're calling an Actionscript extension who's expected to return a String. Here's the java code we would use:
public void callASExtension() { Zone zone = SmartFoxServer.getInstance().getZone("testZone"); AbstractExtension targetExtension = zone.getExtension("asExtension"); // The object we get back is still the "wrapper" object Object responseObj = targetExtension.handleInternalRequest("Hello"); // Finally we unwrap the object and cast it to the expected type String response = (String) responseObj.unwrap(); trace("Response: " + response); }As you can see you only need to remember to call the unwrap() method before casting the object.
» Servlet example
Calling running extensions from a web-server servlet is also very easy. The following example shows how simple is to write a Python servlet that talks to an extension. In this case the target extension is also implemented in Python, so that object exchange is not a concern.
In our example the servlet will accept an external command parameter passed via the query string. The command parameter is then sent to the extension.
from javax.servlet.http import HttpServlet
from it.gotoandplay.smartfoxserver import SmartFoxServer
from java.util import ArrayList
class extensionMonitor(HttpServlet):
def __init__(self):
self.sfs = SmartFoxServer.getInstance()
self.zoneName = "TestZone"
self.extName = "TestExtension"
def doGet(self, request, response):
write = response.getWriter().write
command = request.getParameter("command")
if command:
zone = self.sfs.getZone(self.zoneName)
extension = zone.getExtension(self.extName)
response = extension.handleInternalRequest(command)
write(response)
else:
write("<h2>The command is missing</h2>")
def doPost(self, request, response):
pass
» Application architecture consideration
While this new addition certainly adds more flexibility to the server framework, we would also like to stress that this feature should be used with care or it could lead to horrible application design and poor performance.
Very frequently we have been asked on the support forums about the ability to have multiple extensions running in different Zones talk to each other. In general we don't recommend doing this unless you have a good understanding of the server framework.
In the SmartFoxServer philosophy a ZONE is an "area" of the server where an application is running, and each "areas" should know nothing about the others. This approach leads to the most clean and less error-prone design possible, and we highly discourage to design any advanced multiplayer application basing on multiple Zones talking to each other.
Even the most complex server side application can be cleanly organized in classes with the help of design patterns or other architectural devices, and without the need of using the above mentioned approach.
The main purpose of the interoperability feature is to simplify the communication between extensions in the same Zone or between extensions and other objects.
If you want to learn more about how to organize and design your server side code we highly recommend the following white-papers: