5.4 Tutorials: Advanced Chat (part 1)
The source FLA of this example is available under the Examples/(Actionscript version)/advancedChat folder. |
» Introduction
In this tutorial we will expand the concepts learned in the previous ones and we will enhance the "Simple Chat" demo to make it a more advanced chatting application.
The picture below shows the main GUI (graphical user interaface) of the "AdvancedChat":
Here's a list of the features that we're going to add to the "Simple Chat" example:
» A roomlist
It will show every room available with realtime user count. You will be able to:
-
join any room by clicking on it;
- join password protected rooms;
- create new rooms (with password also).
» A better UserList
By clicking on one user you will be able to send a private message.
» An exit button
By clicking it you will log out of the chat.
» The RoomList
By opening the source .FLA file you will notice that the code in the first two labels is almost identical to the previous sample, so you can safely position the playhead on the "chat" label.
The first thing you should notice in the GUI is the presence of a new listbox called roomList_lb.
Now open the Actionscript panel (F9) and inspect the code for the onRoomListUpdate() event:
smartfox.onRoomListUpdate = function(roomList) { roomList_lb.removeAll() for (var i in roomList) { var room = roomList[i] roomList_lb.addItem(room.getName() + " (" + room.getUserCount() + ")", room.getId()) } roomList_lb.sortItemsBy("label", "ASC") // Join the default room this.autoJoin() }
The first line makes sure that no item is present in the listbox. Then we proceed by iterating through the roomList array and we add each room name to the listbox (plase note that the label is built by joining the room name and the user count for that room).
Once the list is populated we can sort it in ascending alphabetical order.
Just like we did in the other tutorials we call the autoJoin() method to automatically join the default room.
NOTE
Using the autoJoin() method is not mandatory but it is usually easier, if you always need to bring the "just-arrived" users in a default room. Also the autoJoin() method works only if you have defined an autoJoin room in the zone, if none was defined the call will fail.
» Updating the Room status
Now that we have a complete list of rooms with the number of users for each of them how do we know when something changes? What happens if two users exit one room? SmartFoxServer will send you notices of these changes, so all we need to do is writing the appropriate handler for the onUserCountChange event.
smartfox.onUserCountChange = function(roomObj) { updateRoomStatus(roomObj.getId()) }
Every time the event is fired the server passes a Room object that represents the room in which the change occured.
We have setup a simple function called updateRoomStatus that will take care of changing the label in the room list component.
function updateRoomStatus(roomId) { var room = smartfox.roomList[roomId] var newLabel = room.name + " (" + room.getUserCount() + ")" for (i=0; i < roomList_lb.getLength(); i++) { var item = roomList_lb.getItemAt(i) if (roomId == item.data) { roomList_lb.replaceItemAt(i, newLabel, item.data) break; } } }
The function takes the Id of the room and loops through the list box items until it finds the right item. Then it changes its label updating the user count.
» Joining another Room
At the very beginning of the code you will find these lines:
//---------------------------------------------------------- // Setup components callback functions //---------------------------------------------------------- roomList_lb.setChangeHandler("changeRoom") userList_lb.setChangeHandler("userSelected")
They set the name of the function to call when an item in the list component is clicked. We'll concentrate on the changeRoom() method for now:
function changeRoom() { var item = roomList_lb.getSelectedItem() // new Room id var newRoom = item.data if (newRoom != smartfox.activeRoomId) { // Check if new room is password protected var priv = smartfox.getRoom(newRoom).isPrivate() if (priv) { // Save newroom as _global for later use _global.newRoom = newRoom showWindow("passwordWindow") } else { // Pass the room id smartfox.joinRoom(item.data) } } }
The code checks that the room we've selected is different from the one we're currently in, and it uses a SmartFoxClient property that we haven't met yet: activeRoomId. This property always holds the Id of the last room we've joined.
Another important check we have to do is controlling if the room is password protected.
var priv = smartfox.getRoom(newRoom).isPrivate()
The getRoom(id) method returns a Room object. The isPrivate() is a Room method: it returns a boolean (true = password needed, false = no password).
If the room has no access restrictions we can join it by simply using smartfox.joinRoom() and passing the room Id to it.
smartfox.joinRoom(item.data)
If the room needs a password we need to do some extra operations:
1) save the Id of the room we want to join somewhere for later use (_global.newRoom = newRoom)
2) show a dialog box and wait for user input (see previous tutorial)
3) finally send the login and password: smartfox.joinRoom(_global.newRoom, pwd)
Once the password is submitted the dialog box will call the loginProtectedRoom() method in the main timeline:
function loginProtectedRoom(pwd) { hideWindow("passwordWindow") smartfox.joinRoom(_global.newRoom, pwd) }
which in turn sends the previously saved room Id and the password.
NOTE
We have used the joinRoom() method with one argument for rooms with no passwords and with two arguments when a password is needed. For completeness, the full set of arguments is this:
joinRoom = function(newRoom, pword, isSpectator, dontLeave, oldRoom)
SmartFoxServer allows a user to be present in more than one room at a time. This can be useful for complex applications where you need more advanced user interaction. However to keep things simple the joinRoom method leaves the current room by default before entering a new one as this is the most common behaviour for most applications.
If you need to stay in one room while joining a new one you can pass the dontLeave parameter as true.
One more thing about the newRoom argument: you can both pass the room Id or the room name as first parameter.
Now that we have sent our joinRoom request we should be prepared to receive complaints by the server.
For example the server may generate an error if the room we're trying to join is already full. Antoher error could be generated if the password sent is wrong.
The onJoinRoomError is responsible of handling such event:
smartfox.onJoinRoomError = function(errorMsg) { var win = showWindow("errorWindow") win.errorMsg.text = errorMsg // Put the selected room in the combo box back to its old value resetRoomSelected(smartfox.activeRoomId) }
The first two lines will show an error window and the text box inside the dialog box will show the error message passed by the server.
The next line invokes the resetRoomSelected(): this is a little "trick" that we use to restore the selected item in the room list component if the joinRoom request fails.
doc index |