5.17 Tutorial: External Zone Statistics
The example sources can be found under the Examples/AS2/zoneCount folder. |
» Introduction
Since SmartFoxServer 1.5.0 we introduced a simple way to get the number of users logged in the server from an external client, like a PHP/ASP/JSP page or a SWF file. The operation is done by anonymously connecting to the server and sending a simple XML formatted request.
» How it works
The steps to get informations about one or more Zones are the following:
<msg t='sys'><body r='-1' action='zInfo'>zoneName</body></msg>where zoneName is the name of the zone that you want to inspect. You can also pass more multiple names, separating them with commas.
The server will respond with an XML message containing the number of users for each zone requested (comma separated).
Example:
<zInfo>255</zInfo>or
<zInfo>255,100,20</zInfo>
» PHP Sample script
The following code shows an implementation in PHP
<?php $port = 9339; $addr = "127.0.0.1"; // Output basic HTML header echo "<html><head><title>SmartFoxServer Zone Count Demo</title></head><body style='font-size:70%; font-family:Arial'>"; // Create a socket object $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); if ($socket < 0) { trace("Socket errror: " . socket_strerror($socket)); die(); } else trace("Socket object created"); // Establish connection $result = socket_connect($socket, $addr, $port); // Check connection if ($result < 0) { trace ("Received: " . socket_strerror($result)); } else { trace("Connection successfull"); $handShake = "<msg t='sys'><body r='-1' action='zInfo'>simpleChat</body></msg>" . chr(0); socket_write($socket, $handShake, strlen($handShake)); // Wait for server response while(true) { $out = socket_read($socket, 1024); trace("Received: " . htmlspecialchars ($out)); if (strpos($out, "zInfo") > 0 ) { $users = substr($out, 7); $users = substr($out, strpos($user, "<")); echo("<h2>Users in zone: $users<h2>"); break; } } // Close html tags echo "</body></html>"; socket_close($socket); } function trace($msg) { echo "--> " . $msg . "<br/>"; } ?>
In the first lines we start by creating a socket object and establish a connection to the provided address and port.
If the operation is successful
we can send the XML request to the server and pass the zone name(s) that we need.
The following while(true) loop waits for a server response that contains the expected zInfo token. Not necessarily the first response sent by the server is going to be what we expect: for instance if the auto-policy option is turned on the server will send the client the crossdomain policy data first, which is not what we need.
Once the zInfo tag is found we simply read its data (by skipping the token characters), output the result to the html page and finally break the while loop.
» Flash Sample script
If you want to display the number of users inside a SWF file you can directly connect to the server and retrieve the XML data using an XMLSocket connection.
The following is an example of how to do it:
var request:String = '<msg t="sys"><body r="-1" action="zInfo">simpleChat</body></msg>' var zeros:String = "000" // Create a socket connection var conn:XMLSocket = new XMLSocket() conn.onConnect = connected conn.onClose = closed conn.onData = gotData // Connect to SmartFoxServer conn.connect("127.0.0.1", 9339) // Handle connection to the server function connected(ok:Boolean) { // Connection successfull: send message to server if (ok) { trace("---> Connected") this.send(request) } } // Connection was closed function closed():Void { trace("---> Lost") } function gotData(msg:String) { // Check if this is the message we're expecting if (msg.indexOf("zInfo") > -1) { var xml:XML = new XML(msg) var count:String = xml.firstChild.childNodes[0].toString() // Format the number userCount.text = zeros.substr(0, 3 - count.length) + count // Close connection conn.close() } }
The socket connection is established using the XMLSocket object and it is handled by the onConnect() and onData() methods. The former checks if the connection was successful and sends the XML request, the latter handles the message received from the server and parses them.
When the zInfo token is detected we simply extract the data from the string and display it in the textfield on Stage called userCount.
If you're wondering why we didn't parse the XML data instead of manipulating the string, the reason is that the server response is so simple that it takes more code to do the XML parsing than just analyzing the plain string data.
» Using the embedded webserver (PRO only)
SmartFoxServer PRO 1.5.0 comes with a powerful embedded webserver that integrates with the SmartFoxServer framework.
If you're serving your application files from the embedded webserver it is very easy to show the current status of the server. An example of how to get the current server status is provided in the webserver/webapps/examples/ folder.
Open the ServerInfo.py file:
from javax.servlet.http import HttpServlet from it.gotoandplay.smartfoxserver.webserver import WebHelper class ServerInfo(HttpServlet): def __init__(self): self.htmlHead = "<html><head></head><body style='font-family:Verdana'>" self.closeHtml = "</body></html>" # # Handle GET requests # def doGet(self, request, response): w = response.getWriter() w.println(self.htmlHead) status = WebHelper.getServerStatus() keys = status.keySet() w.println("<h2>SmartFoxServer :: Status</h2><hr>") w.println("<table cellpadding='6' cellspacing='0' border='0'>") w.println("<tr bgcolor='#eeeeee'><th align='left'>Key</th><th align='left'>Value</th></tr>") for key in keys: w.println("<tr>") w.println("<td>%s</td><td>%s</td>" % (key, status[key])) w.println("</tr>") w.println("</table><hr>") w.println(self.closeHtml) w.close() # # Handle POST requests # def doPost(self, request, response): pass
The doGet() handles a "regular" GET request to the webserver, which is what we expect in this case. (a POST request is handled when a form-data is sent to the page)
In order to access the SmartFoxServer status we have to first import the it.gotoandplay.smartfoxserver.webserver.WebHelper object.
The WebHelper class has a getServerStatus() method that returns a map (java.util.Map) of values with the following keys:
zones | the number of active zones |
rooms | number of active rooms |
users | the number of active users |
uptime | the SmartFoxServer uptime |
version | current server version |
In order to check the provided example you should open a browser page and point it to http://127.0.0.1:8080/examples/ServerInfo.py
(unless you have changed the default IP/port configuration parameters)
doc index |