| Ryerson Home > Ryerson Flash Communication Development Server > Flash/FlashCom Programming Notes |
These notes are based on my experience reviewing student work, fixing bugs, reading about problems on various FlashCom mailing lists, and reviewing preproduction code. They are an attempt to help people at Ryerson (students and staff) who are writing Flash/FlashCom code. For more official recommendations about things like style and good coding practices, see Macromedia's site. In particular check:
Also, while not about ActionScript, you may find this useful:
This page is very ad hoc and will grow whenever I have a chance to add to it. Also, I have simplified some of the code samples. Consequently, there is a small chance I have introduced new problems.
This sample code has two problems:
//---------------lobby Net Connection----------//
lobby_nc = new NetConnection();
lobby_nc.onStatus = function(info) {
trace("info: "+info.description);
};
//-------------connecting to Server--------------//
lobby_nc.connect("rtmp://"+server+"/mmsLobby/Lobby");
//---------------Shared Objects-------------------//
lobby_so = SharedObject.getRemote("Lobby", lobby_nc.uri, false);
//connecting to lobby net connection.
lobby_so.connect(lobby_nc);
lobby_so.onSync = function(list) {
//clear the game list box.
loginScreen_mc.game_lb.removeAll();
//loop through all properties of the shared object
for (var i in lobby_so.data) {
//add the games to the list box.
trace("lobby info: " + list.description);
loginScreen_mc.game_lb.addItem(lobby_so.data[i].name, lobby_so.data[i].status);
}
};
This sample could be recoded a number of ways. Here is one possibility:
/**
* initLobbySharedObjects initializes a shared object and connects it
* to the remote Lobby shared object after the network connection
* is established. In this example it is called within the onStatus
* handler of the lobby_nc net connection.
*/
function initLobbySharedObjects(nc){
lobby_so = SharedObject.getRemote("Lobby", nc.uri, false);
lobby_so.onSync = function(list) {
//clear the game list box.
loginScreen_mc.game_lb.removeAll();
//loop through all properties of the shared object
for (var i in lobby_so.data) {
//add the games to the list box.
trace("lobby info: " + list.description);
loginScreen_mc.game_lb.addItem(lobby_so.data[i].name, lobby_so.data[i].status);
}
}
lobby_so.connect(nc);
}
//---------------lobby Net Connection----------//
lobby_nc = new NetConnection();
lobby_nc.onStatus = function(info) {
trace("info: "+info.description);
if (info.code == "NetConnection.Connect.Success"){
initLobbySharedObjects(this);
}
}
lobby_nc.connect("rtmp://"+server+"/mmsLobby/Lobby");
This guarantees that:
However, it doesn't deal with the problem of having to hard-code in the name of the list box that the onSync method must update. The answer to that problem is to make the shared object an event broadcaster and let delegate objects handle event processing. Another problem is that no onStatus method is defined. There should be one.
Here is a code sample from a simple FlashCom server-side main.asc file followed by some suggestions for improvements:
application.onAppStart = function() {
application.LogHash = new Object();
};
application.onConnect = function(NewClient) {
application.acceptConnection(NewClient);
NewClient.pingServer = function(){
return;
}
NewClient.loginPlayer = function(player){
if(application.LogHash[player] == undefined){
application.LogHash[player] = player;
NewClient.name = player;
return "player logged";
}else{
return "player exists";
}
}
};
application.onDisconnect = function(client) {
application.LogHash[client.name] = null;
};
Here are some comments/suggestions:
NewClient.pingServer = function(){
return;
}
do this outside of any application method:
Client.prototype.pingServer = function(){
return;
}
The same thing should be done with the loginPlayer method.this to assign a property to an object inside an object
method. This does work:
NewClient.loginPlayer = function(player){
NewClient.name = player;
}
but consider doing this instead - I think it is less likely to lead to to
problems:
NewClient.loginPlayer = function(player){
this.name = player;
}
application.LogHash[player] = player;It seems redundant. Also on the server-side you don't always have to compare a string to undefined the way you do on the client side this way:
if(application.LogHash[player] == undefined){
If you don't mind an empty string evaluating to false you could do this:
// Don't try this in Flash:
if(application.LogHash[player]){
In any case, if you store the boolean value true in the hash
then you don't need to test the string at all:
if(application.LogHash[player]){
return "player exists";
}
else{
This is largely a matter of style. ActionScript, unlike ECMAScript/JavaScript/JScript
evaluates all strings as false so you have to test if they are equal to undefined
on the client.application.LogHash[client.name] = null;instead use the delete keyword like this to remove it entirely from the hash:
delete application.LogHash[client.name];In this case when a client disconnects it may or may not have a name property. You can show this explicitly in the code this way:
if (client.name != undefined){
delete application.LogHash[client.name];
}
even though it is not strictly necessary. If you don't want to code the if
statement at least include a comment.Here is the rewritten code:
/**
* pingServer is called by the client to determine the
* time it takes to call a remote method and get a
* response. The function does nothing but return.
* The timing of the round trip is done on the client.
*/
Client.prototype.pingServer = function(){
return;
};
/**
* loginPlayer is called by the remote client
* to give itself a name. If the name is already
* taken the client is told the name already exists.
*/
Client.prototype.loginPlayer = function(player){
if(application.LogHash[player]){
return "player exists";
}else{
application.LogHash[player] = true;
this.name = player;
return "player logged";
}
};
application.onAppStart = function() {
// Create a hash to store player names in.
application.LogHash = new Object();
};
application.onConnect = function(newClient) {
application.acceptConnection(newClient);
};
application.onDisconnect = function(client) {
// Not all clients will have a name.
if (client.name != undefined){
delete application.LogHash[client.name];
}
};
Finally logHash isn't that descriptive. Something like playerNames
would have been better.
This document was written by Brian Lesser and last updated: