5.3 Tutorials: Simple Chat (part 2)
The source FLA of this example is available under the Examples/(Actionscript version)/simpleChat folder. |
» Introduction
In this second chapter of the "Simple Chat" application we would like to discuss a little more in detail some aspects of the code created in part 1. The previous tutorial focused its attention on how to quickly build a simple chat application and we intentionally left out some topics that deserve some extra explanation.
» Connect - Login - Join
As you have noticed we have taken three main actions in the previous code example:
Connect
At first we try to establish a connection to the server using its ip address
and port. This is just like knocking at someone's door. You don't enter in
the house, you just ask if there's anybody at home. In case you don't get any
responses then you won't be able to ask anything else.
Login
If the server responded you can tell who you are and see if the server accepts you.
In our case you will always be accepted unless you use a user name that is already in use.
Join
Once you're "inside" you will be able to choose which room you want to enter.
This is determined by the "zone" in which you asked to log in. You can think of "zones" as if they were different houses, each of them with its different set of rooms. Some can be very small with a few rooms and others can be huge and with many many rooms.
Once these three steps are taken successfully you're enabled to interact with all the other users.
Below follows a table with the typical request-response pattern that you would normally use to do the connect-login-join:
Client Request | Event fired by Server |
server.connect(ip, port, zone) | onConnect() |
server.login(name, password) | onLogin() onRoomListUpdate() |
server.joinRoom(roomId) or server.autoJoin() |
onJoinRoom() or onJoinRoomError() |
» The RoomList : Room and User objects
Two of the most important SmartFoxServer events are called onRoomListUpdate() and onJoinRoom().
What makes them special is the fact the they populate some data structures in the SmartFoxClient object and I'd like to take a deeper look at it.
The following picture represents the SmartFoxServer internal data structure and you have already seen it in the first part of this tutorial:
The server (at the root of the diagram) holds a list of zones, each running a different application.
Each zone contains a list of rooms which in turn contain users.
While the server always sees all this big structure, the client has a smaller perspective as every user is always connected in just one zone at a time. So the SmartFoxClient object is populated with a list of Rooms (those owned by the zone in which we are connected) and every Room will have its own list of users.
The picture below shows this in detail:
The roomList is an array and it is populated with Room objects when the onRoomListUpdate event is fired: each Room object can be accessed using the methods shown under the Room Object.
The userList is an array and it is populated with User objects when the onJoinRoom event is fired: each User object can be accessed using the methods shown under the User Object.
If you go back to the previous article and source code, you will notice that we already used these objects and methods but now you should have a better understanding of what's going on "behind the scenes" and be able to experiment on your own.
» Handling errors
One important thing to consider in every project is how to manage unexpected conditions and errors.
Also sometimes it is necessary to stop the normal flow of the application, for example to get some input from the user and we would also like our UI to behave in a different way (i.e. disable certain part of it until the user submits data).
In our "Simple Chat" demo we can get two types of errors:
» a login error, if you try to enter with an already existing user name
» a join error, if you try to join a room that's already full
To test these conditions, try launching two instances of the "Simple Chat" sample and log in with the same name: the second time a dialog window will popup in the middle of the screen and the rest of the application will be grayed out. The application will restore its state when you will press the "OK" button.
We'll use this simple system quite a lot in all the next tutorials every time we will need a dialog box:
- sending a private message
- entering a password protected room
- creating a new room
- creating a new game room
- showing system and error messages
You can find the code that handles the dialog boxes under the "connect" label in the source .FLA of the "SimpleChat".
Mainly we use two functions: showWindow(), hideWindow()
function showWindow(linkageName) { _global.isBusy = true userList_lb.setEnabled(false) disabler._visible = true var win = _root.attachMovie(linkageName, linkageName, 9999) win._x = (stageW / 2) - (win._width / 2) win._y = (stageH / 2) - (win._height / 2) return win }
The "linkageName" argument is the linkage identifier of the symbol in the library, so if you plan to add you own custom windows always remember to export them for "Actionscript". If you inspect the library in the .FLA you will find a "_windows" folder with all the dialog boxes needed by the application and if you right-click (win) or ctrl-click(mac) on each of them you will notice that they all have a linkage id.
The _global.isBusy boolean is tested everytime a button in the interface is pressed. This way we can disable all buttons in the GUI just by setting this global variable to "true".
The variable called "disabler" refers to a movieclip (check the layer called "disabler") that will cover the entire stage with a semi-transparent black square (this enforces the idea that the main interface has been temporarily "freezed").
The code continues by attaching the dialog box movieclip on stage, then the clip is centered in the screen and a reference to it is returned by the function so you can furtherly manipulate it.
Now double click on the "errorWindow" movieclip in the library and select the "OK" button then open the Actionscript panel (F9).
You will notice that we have just one command, closeMe(), and you will find it's code in the main timeline of the "errorWindow" movieclip.
_parent.hideWindow(this._name)
This command invokes the hideWindow() function in the parent timeline passing the movieclip instance name as an argument. This way the hideWindow() method can destroy the window and re-enable the GUI controls.
In the next tutorials we will use also input dialog boxes and we will use almost the same approach. The only thing we'll change is that the button will not directly call the closeMe() function, instead it will call a function in the main timeline that will read the input data and then invoke the hideWindow() method.
doc index |