views:

1083

answers:

4

I've been struggling with this for the past couple hours now and I really don't know what could be wrong. I'm simply trying to get Javascript to communicate text with Flash. I found this great example with this source

http://blog.circlecube.com/wp-content/uploads/2008/02/ActionscriptJavascriptCommunication.zip

I ran the html file locally and it works just fine sending and retrieving text from flash. Then I load that same exact sample into my dev google app server and I can't send the text from javascript to flash. Oddly enough though flash is able to send Javascript text. Can anybody see if they can get this running with GAE? Thanks a million!

A: 

It probably doesn't have to do with Google app engine per se, since the whole thing's running in the browser -- unless there's some sort of server dependency somewhere you haven't mentioned. Assuming that's not the case...

If you're able to get Flash to call into JavaScript with ExternalInterface.call(), but not JavaScript to call back into Flash, then it's probably one or two things: your EI callback & handler aren't wired up properly (in Flash), or your JavaScript doesn't have a handle on the SWF object in the browser.

You might try posting some code, but in the meantime, here's something I know works in both IE and FireFox. First, the browser code:

<html>
<head>
<script language="JavaScript" type="text/javascript">

    var swfReady = false;

    function callbacksInitialized()
    {
     swfReady = true;
    }

    function helloFlash()
    {
     if (swfReady)
     { 
      // Get a handle on the Flash object
      var swfObject = navigator.appName.indexOf("Microsoft") != -1 ? window["HelloMac"] : document["HelloMac"] ;

      // Call back into the Flash file 
      swfObject.helloFlash(document.getElementById("txtMessage").value);
     }
    }

    function helloMac(message)
    {
     alert(message);
    }

</script>
</head>
<body scroll="no">
    <div align="center">

     <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
       id="HelloMac" width="600" height="300"
       codebase="http://fpdownload.macromedia.com/get/flashplayer/current/swflash.cab"&gt;
       <param name="movie" value="HelloMac.swf" />
       <param name="quality" value="high" />
       <param name="bgcolor" value="#869ca7" />
       <param name="allowScriptAccess" value="sameDomain" />
       <embed src="HelloMac.swf" quality="high" bgcolor="#869ca7"
        width="600" height="300" name="HelloMac" align="middle"
        play="true"
        loop="false"
        quality="high"
        allowScriptAccess="sameDomain"
        type="application/x-shockwave-flash"
        pluginspage="http://www.adobe.com/go/getflashplayer"&gt;
       </embed>
     </object>

     <br /><br />
     <input type="text" id="txtMessage" value="Hello, Flash!" /><br />
     <input id="btnSend" type="button" value="Send to Flash" onclick="helloFlash();" />
    </div>
</body>
</html>

And now, the Flash code (in my case, it's Flex, so hopefully it's clear):

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" initialize="init()" height="300" width="600">

    <mx:Script>
     <![CDATA[

      import mx.controls.Alert;
      import flash.external.ExternalInterface;

      private function init():void
      {
       addCallbacks(); 
      }

      private function addCallbacks():void
      {
       ExternalInterface.addCallback("helloFlash", this_helloFlash);
       ExternalInterface.call("callbacksInitialized");
      }

      // Display a message from the host
      private function this_helloFlash(message:String):void
      {
       Alert.show(message);
      }

      // Send a string to the host
      private function helloMac():void
      {
       if (ExternalInterface.available)
       {
        ExternalInterface.call("helloMac", txtMessage.text);
       }
      }

     ]]>
    </mx:Script>

    <mx:VBox horizontalCenter="0" verticalCenter="0">
     <mx:TextInput id="txtMessage" text="Hello, Mac!" />
     <mx:Button id="btnSend" label="Send to Host" click="helloMac()" />
    </mx:VBox>

</mx:Application>

The example demonstrates Flash calling into JavaScript with some text, and JavaScript calling back into Flash in the same way. Some points to pay attention to:

  • Make sure you wait to call into Flash until Flash has notified the browser it's ready to begin receiving calls (as indicated by my callbacksInitialized() method).
  • Test to be sure you're using the appropriate browser-specific object reference (e.g., window["HelloMac"] vs. document["HelloMac"]).

Without knowing more, I'm guessing it's one of these two items, since that's been my experience. Hope it helps! I'll keep an eye on the post for follow-ups in case you have any.

Christian Nunciato
A: 

Yup the answer by Christian Nunciato is helpful. The issue is that your swf file is not available to javascript at the time your javascript calls the flash function. Christian's trick makes sure the swf file is loaded and started when your javascript needs it.

pixeline
A: 

Hey Christian,

Thanks a lot for your help I really appreciate it. Unfortunately that is definitely not the problem :(. I guess I must have been mistaken that the flash could communicate with javascript cause I tried it again and it cannot. I posted my examples... they both use the same exact html file and same exact swf file:

lets-tango.appspot.com <- hosted on google app engine

digitillusion.ethereallan.org/external <- hosted on my server

if you use firebug you'll notice that your callbacksInitialized() is hit on the 2nd one but not the first.

here is the actionscript:

import flash.external.*;

//Set up Javascript to Actioscript
var methodName:String = "sendTextFromHtml";
var instance:Object = null;
var method:Function = recieveTextFromHtml;
addCallBacks();

function addCallBacks(){
var wasSuccessful:Boolean = ExternalInterface.addCallback(methodName, instance, method);
ExternalInterface.call("callbacksInitialized");
}

//Actionscript to Javascript
//ExternalInterface.call("recieveTextFromFlash", _root.theText.text);

function recieveTextFromHtml(t) {
    _root.theText.text = t;
}

_root.button.onRelease = function() {
    ExternalInterface.call("recieveTextFromFlash", _root.theText.text);
    _root.theText.text = "";
}

if you or anybody else has any ideas what might be up pleeeease let me know! This is killing me! thanks for your time!

Ack, sorry for the delay -- I didn't notice you posted this. Next time, post a comment! I keep a close eye on those but not as much on the original threads. I'll take a look now. Cheers. :)
Christian Nunciato
Ah, are you working in Flash with ActionScript 2?
Christian Nunciato
+1  A: 

I do not see a call to the allowDomain function in your code. With out that the security sandbox will not allow your flash application to communicate with flash and vice versa on the server. Add a call to System.security.allowDomain("mydomain.com", "mySecondDomain.com", "etc.com") for every domain the flash app will be executed on. Also the embed code also needs to specify access for JavaScript by including the parameter <param name="allowScriptAccess" value="always" />.

Kelly Anderson