8.5 Tutorials: Login Extension
The source FLA of this example is found under the Examples/AS2/pro_loginExample folder. |
» Introduction
With this article we'll start seeing how to handle the server internal
events and how they can be useful to create advanced server behaviors.
The example application is based on the simpleChat tutorial,
one of the first and most simple tutorials of the SmartFoxServer
Basic series.
The new example will show you how to intercept a "loginRequest" server
event and use it to create your own login custom logic.
» Internal Events
Internal server events are fired by the server engine each time an "interesting"
action is executed. For example a login request has just arrived, or a new user
just entered a Room in the current Zone etc...
The available server events are:
userJoin | a user has joined the room / zone | |
userExit | a user has left the room | |
userLost | a user was disconnected | |
newRoom | a new room was created in the zone | |
roomLost | a room was destroyed in the zone | |
loginRequest | a client is requesting to log in | |
spectatorSwitched | a spectator in a game room was turned into a player |
Depending on the Level of your extension, it will
be able to handle all of them (Zone Level) or only a part
of them (Room Level: userJoin, userExit, userLost). You can
find more info about extension levels in the tutorials
intro and in Server-Side Actionscript
API documentation.
» Handling the login event
Before we dive in the code it's important to remember that the loginRequest event
can be activated or deactivated from the Zone configuration
in your config.xml file. By changing the customLogin attribute
to true or false you can toggle the notification of this event. By default it
is set to false.
For this example we will use the simpleChat Zone and we'll set customLogin="true" to
make sure we'll be able to handle the loginRequest event.
Below you can see a simple diagram of how a login request is handled by the server,
broadcasted to the extension and finally verified back by the server engine:
1) The client sends a login request, using the already known login(zone,
name, password)
method from the client side API.
2) The server checks if the Zone where the user wants to connect
has the customLogin attribute
turned on. If so the event is broadcasted to all Zone Level estensions.
3) In the above diagram we pretend that the extension C
handles the login request. The user credentials are verified by your custom code
and, if the check is passed, you will have to ask the server to finally allow
this user in.
A this point some questions may arise:
Why do I have to do this? If my custom logic says the user is valid why should
I ask the server to allow this user?
There are still some extra system checks to pass before the server permits a
new user to log in. The server will check if the user name is not duplicated
in the Zone, if the user IP address is not banned, if the user name is not banned,
if the Zone has room for this client etc...
By passing this final tests the user will be successfully logged inside the requested
Zone.
» The client side
The client side code is almost identical to the original, non extension-based
example. We have just added a new input field for the user password.
Here's the code for the login request:
function sendLogin() { if (!_global.isBusy) smartfox.login(zone, login_txt.text, pwd_txt.text) }
var userList function init() { // Simple list of users // The key is the username, the value is the password userList = new Object() userList["tom"] = "tom" userList["jerry"] = "jerry" userList["smart"] = "fox" } function destroy() { trace("Bye bye!") } function handleRequest(cmd, params, user, fromRoom) { // no requests to handle here... } function handleInternalEvent(evt) { if (evt.name == "loginRequest") { var error = "" var nick = evt["nick"] var pass = evt["pass"] var chan = evt["chan"] if (userList[nick] != pass) { error = "Authentication failed" } else { var obj = _server.loginUser(nick, pass, chan) if (obj.success == false) error = obj.error } // Send response to client var response = new Object() if (error == "") { response._cmd = "logOK" } else { response._cmd = "logKO" response.err = error } _server.sendResponse(response, -1, null, chan) } }
smartfox.onExtensionResponse = function(resObj:Object) { if (resObj._cmd == "logOK") { // Login Successful _global.myName = resObj.name gotoAndStop("chat") } else if (resObj._cmd == "logKO") { // Login Failed _gloabl.isBusy = true // Show an error window var win = showWindow("errorWindow") win.errorMsg.text = resObj.err } }
doc index |