Section 9.7. Debugging Calls

9.7. Debugging Calls

Debugging in Flash is relatively difficult, and trying to debug client/server interactions is even harder. Luckily, some helpful tools and methods are built into the communication objects' classes.

9.7.1. The Communication App Inspector Is Your Best Friend

For any FlashCom developer, the Communication App Inspectoras described in Chapter 4 under "Testing and Debugging Server-Side Script Files"is an irreplaceable tool for debugging every aspect of your client/server applications. When dealing with remote calls, it is important to know if your client-to-server or server-to-server calls are getting triggered at the right time, with the right number of arguments, or if your server-to-client calls are failing for any reason. The App Inspector's Live Log tab displays the output from any trace( ) statements in SSAS, which helps monitor and debug all these interactions.

A handy trick is to create a shortcut to app_inspector.swf (usually found in the flashcom_help\html\admin\ folder under your server's directory). This will give you one-click access to the App Inspector, even when the Flash authoring tool is not running, and will let you open more than one instance of it easily.

Let's look at some common errors and ways to fix them.

9.7.1.1 Error: msg sent before connection established

If you see the error message "Error: msg sent before connection established" in your application's live log in the App Inspector, you have a flaw in your server-side code logic. Most often, this means that you tried to invoke a method on a client before accepting the connection from that client.

This code, for instance, will trigger that warning:

 application.onConnect = function (client) {   // This is wrong.   client.call("test", null, 123);   application.acceptConnection(client); }; 

The correct code would have the order of the Client.call( ) and application.acceptConnection( ) calls reversed ; you need to accept a client's connection before making server-to-client calls on that client. The error might look pretty obvious in the preceding example, but the connection logic could be much more complex (as we will see in Chapter 18), so having the server warn us when we accidentally call a method on a client before we accept its connection is very useful.

The same error message is also triggered if you try to make a server-to-client call to a client that no longer exists (i.e., after it disconnects).

9.7.2. Debugging Server-to-Server Calls

When debugging server-to-server calls, it's very useful to open two instances of the App Inspector and put them side by side, one looking at the calling instance's logs, the other at the responding instance's logs. It's a small trick, but invaluable when debugging server-to-server calls.

9.7.3. Trapping onStatus Whenever Possible

ActionScript, on both the client and server sides, provides methods to debug your application and deal with runtime failures. The main debugging tool for remote method invocations is trapping the onStatus event in an onStatus( ) handler.

Look at this example of a client-to-server call:

 var resObj = new Object(  ); resObj.onResult = function (val) {   trace("The time on the server is:" + val);   _root.serverTime_txt.text = val; }; resObj.onStatus = function (info) {   trace("getServerTime.onStatus: " + info.code);   for (var i in info)     trace(" " + i + ": " + info[i]); }; nc.call("getServerTime", resObj); 

It's the same example we saw at the beginning of this chapter, but with an onStatus( ) method added to the result object. This method will get called by the Flash Player whenever there's a problem with the call.

The same technique (defining an onStatus( ) method on the result object) applies to Server-Side ActionScript, but with a twist. On the server side, in fact, Client.call( ) returns a Boolean value, which tells us whether the call was sent or failed immediately. Look at this example:

 AreYouOkResultHandler = function (clientID) {   this.clientID = clientID; }; AreYouOkResultHandler.onResult = function (val) {   trace("Client " + this.clientID + " returned " + val); }; AreYouOkResultHandler.onStatus = function (info) {   trace("Call to areYouOk to " + this.clientID         + " failed asynchronously: " + info.code); }; application.someFunction = function (client, clientID) {   var callSent = client.call("areYouOk",                   new AreYouOkResultHandler(clientID));   if (!callSent)     trace("Call to areYouOk to " + clientID + " failed synchronously!"); }; 

Notice how we deal with potential failures in two different ways: we create an onStatus( ) method on the result object, which will get called if there is a problem with the execution of the call; furthermore, we use the callSent variable to check the return value of the call, which tells us whether the call executed at all. The return value may be false if the server has already disconnected the client we are trying to invoke, for example.

The info object returned as a parameter to the onStatus( ) call (on both the client and server sides) contains the following properties:


code

Will have the value "NetConnection.Call.Failed" if an error occurred


description

Will have the value "Method not found (methodname)" if the method was not defined; will have the value "Failed to execute method (methodname)" if the execution of the remote method generated a runtime error


level

Will be "error"

If you don't need the fine granularity of having a different onStatus( ) handler for each result call, you can define a global onStatus( ) handler and attach it to your NetConnection object on the client side and to the application object on the server side. This will trap all errors that aren't caught by per-call onStatus( ) handlers. Look at this server-side code, for example:

 application.onStatus = function (info) {   for (var i in info)     trace("-" + i + ": " + info[i]); }; 

Because this is a more generic onStatus( ) handler, which catches all sorts of application-wide errors, the info object on the server side will have slightly different values:


code

Will have the value "Application.Script.Error" if an error occurred


description

Will have the value "Method not found (_error:69882672)" if the method was not found or the method generated a runtime error


level

Will be "error" in case of an error; "status" otherwise

Hopefully you will find these debugging techniques helpful in diagnosing application problems, resulting in more error-resilient code.



Programming Flash Communication Server
Programming Flash Communication Server
ISBN: 0596005040
EAN: 2147483647
Year: 2003
Pages: 203

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net