0
votes

Well here's a problem.

I've got a website with large javascript backend. This backend talks to a server over a socket with a socket bridge using http://blog.deconcept.com/swfobject/

The socket "bridge" is a Flex/Flash .swf application/executable/plugin/thing for which the source is missing.

I've got to change it.

More facts:

file appExePluginThing.swf
appExePluginThing.swf Macromedia Flash data (compressed), version 9

I've used https://www.free-decompiler.com/flash/ to decompile the .swf file and I think I've sorted out what's the original code vs the libraries and things Flash/Flex built into it.

I've used FDT (the free version) to rebuild the decompiled code into MYappExePluginThing.swf so I can run it with the javascript code and see what happens.

I'm here because what happens isn't good. Basically, my javascript code (MYjavascript.js) gets to the point where it does

    window.log("init()");
    var so = new SWFObject("flash/MYappExePluginThing.swf"", socketObjectId, "0", "0", "9", "#FFFFFF");
    window.log("init() created MYappExecPluginThing!!!");
    so.addParam("allowScriptAccess", "always");
    log("init() added Param!!");
    so.write(elId);
    log("init() wrote!");

IE9's console (yeah, you read that right) shows

init()
created MYappExecPluginThing!!!
init() added Param!!
init() wrote!

but none of the debugging i've got in MYappExePluginThing.as displays and nothing else happens.

I'm trying to figure out what I've screwed up/what's going on? Is MYappExePluginThing.as running? Is it waiting on something? Did it fail? Why aren't the log messages in MYappExePluginThing.as showing up?

The first most obvious thing is I'm using FDT which, I suspect, was not used to build the original. Is there some kind of magic "build javascript accessible swf thing" in FlashBuilder or some other IDE?

First noteworthy thing I find is:

file MYappExePluginThing.swf
MYappExePluginThing.swf  Macromedia Flash data (compressed), version 14

I'm using Flex 4.6 which, for all I know, may have a completely different mechanism for allowing javascript communication than was used in appExePluginThing.swf

Does anyone know if that's true?

For example, when FDT runs this thing (I can compile but FDT does not create a .swf unless i run it) I get a warning in the following method:

  private function init() : void
  {
 Log.log("console.log", "MYappExePluginThing init()");
             //var initCallback:String = Application.application.parameters.initCallback?Application.application.parameters.initCallback:"MYjavascript.MYappExePluginThing_init";
     var initCallback:String = FlexGlobals.topLevelApplication.parameters.initCallback?FlexGlobals.topLevelApplication.parameters.initCallback:"MYjavascript.MYappExePluginThing_init";
     try
     {
        ExternalInterface.addCallback("method1Callback",method1);
        ExternalInterface.addCallback("method2Callback",method2);
        ExternalInterface.call(initCallback);
     }
     catch(err:Error)
     {
        Log.log("console.log", "MYappExePluginThing init() ERROR err="+err);
     }
  }

I got a warning that Application.application was deprecated and I should change:

     var initCallback:String = Application.application.parameters.initCallback?Application.application.parameters.initCallback:"MYjavascript.MYappExePluginThing_init";

to:

var initCallback:String = FlexGlobals.topLevelApplication.parameters.initCallback?FlexGlobals.topLevelApplication.parameters.initCallback:"MYjavascript.MYappExePluginThing_init";

which I did but which had no effect on making the thing work.

(FYI Log.log() is something I added:

    public class Log{

        public static function log(dest:String, mssg:String):void{
                if(ExternalInterface.available){
                  try{
                    ExternalInterface.call(dest, mssg);
          }
          catch(se:SecurityError){
          }
          catch(e:Error){
          }
                }
        trace(mssg);            
         }

              }

)

Additionally, in MYjavascript.js MYappExePluginThing_init looks like this:

this.MYappExePluginThing_init = function () {
    log("MYjavascript.js - MYappExePluginThing_init:");
};

Its supposed to be executed when MYappExePluginThing finishes initializing itself.

Except its not. The message is NOT displaying on the console.

Unfortunately, I cannot find any references explaining how you allow javascript communication in Flex 4.6 so I can check if I've got this structured correctly.

Is it a built in kind of thing all Flex/Flash apps can do? Is my swf getting accessed? Is it having some kind of error? Is it unable to communicate back to my javascript?

Does anyone have any links to references?

If this was YOUR problem, what would you do next?

2
The first thing I would do: add a textfield to your stage or root mc and set its text property in your Log.log() function. trace() doesn't serve you (unless you are logging it, which I assume you are not as you didn't mention it). In that way you can clearly see whether some Error (as far as I know only SecurityError is thrown, so you don't need to catch both) is thrown and whether the function is called at all! - maybe there is an error thrown before calling it and it never gets to call the ExternalInterface. - Fygo
@Fygo i don't understand what you mean by "stage or root mc". can you explain? - user1126515
@Fygo does mc mean movie clip? this isn't a movie clip. its an ActionScript wrapper exposing part of the Flex api for use from javascript. - user1126515
What do you mean by that? I have never worked with Flex so I may be wrong here (so take it with a grain of salt) but as far as I know the top level object must be a descendant of Sprite, both mx Application and Spark Application. In that case it is a display object. How do you actually trace whether you are getting some error etc.? You cannot run it without the browser. Are you logging the trace() to some file then? - Fygo
The swf I'm working with exposes the Socket api to my JavaScript. It provides event callbacks that pass data back to the JavaScript and methods to accept data from the JavaScript. There's no visual content unless that's some AS3/flex requirement of which I'm unaware (and that's completely possible) - user1126515

2 Answers

0
votes

(Not a full solution but I ran out of room in the comment section.)

To answer your basic question, there's nothing special you should need to do to allow AS3-to-JS communication beyond what you've shown. However, you may have sandbox security issues on localhost; to avoid problems, set your SWFs as local-trusted (right-click Flash Player > Global Settings > Advanced > Trusted Location Settings). I'm guessing this not your problem, though, because you'd normally get a sandbox violation error.

More likely IMO is that something is broken due to decompilation and recompilation. SWFs aren't meant to do that, it's basically a hack made mostly possible due to SWF being an open format.

What I suggest is that you debug your running SWF. Using break-points and stepping through the code you should be able to narrow down where things are going wrong. You can also more easily see any errors your SWF is throwing.

0
votes

Not really an answer, but an idea to get you started is to start logging everything on the Flash side to see where the breakage is. Since you're using IE, I recommend getting the Debug flash player, installing it, then running Vizzy along side to show your traces.

Should give you a good idea of where the app is breaking down.