OpenLaszloと外部の連携5
ここまででかなりまともにFlashにデータを送信できるようになった訳ですが、実はまだonvalイベントが全然動いてなかったり。
OpenLaszloでは
onidleのタイマーで監視というのもアレですから、
まず、Laszloにはlps/include/embed.jsに定義されているlzSetCanvasAttributeメソッドというのがデフォルトで提供されていて、表向きこれを使ってデータをFlashへ送信することになっています。これはリファレンスあたりをみてもらうとして。
そのlzSetCanvasAttributeから呼ばれている_lzSetCanvasAttributeメソッドを見ると、このメソッドはFlashVarsをターゲットとなるswfファイルではなくlps/include/h.swfというファイルへ送信しています。h.swfにデータを送ったはずがターゲットのFlashファイルの変数に設定される訳です。
実はFlashにはLoacalConnectionという機能があってFlash間のデータをやり取りすることが可能です。実際h.swfはlps-3.3.1-src\lps-3.3.1\lps\includes\source\history.asというActionScriptで作られていて(これはソース付きのLaszloをDLしないと見れないかも)中身はこんな感じです。
outgoing_lc = new LocalConnection(); if (_root.__lzevent != null) { outgoing_lc.send(_root.__lzhistconn, "receiveEvent", _root.n, _root.v); } else { outgoing_lc.send(_root.__lzhistconn, "receiveHistory", _root.h); }
sendの第一引数は__lzhistconnの部分がFlashのユニークなIDで、これで呼び出す先を特定します。第二引数は呼び出すメソッド名です。
呼び出される側のソースはlps-3.3.1-src\lps-3.3.1\WEB-INF\lps\lfc\services\LzHistory.asに定義されています。部分的に抜き出せば
LzHistory.receiveEvent = function(n, v){ _root.canvas[n] = v; _root.canvas['on' + n].sendEvent(v); } LzHistory.makeConnection = function () { var lc = new LocalConnection(); lc.receiveEvent = function(n, v) { _root.LzHistory.receiveEvent(n, v); };
このファイルはLZXファイルがコンパイルされるときにLZXの一部として出力されるSWFファイルに組み込まれるものです。つまりターゲットのSWFファイルはこのreceiveEventメソッドを持っていてh.swfから呼び出される準備があるわけです。
注目すべきは
_root.canvas['on' + n].sendEvent(v);
ですね。これでonvalイベントが呼び出せそうです。
いくつか注意点があります。まず__lzhistconnはFlashを特定するユニークなIDでなければなりません。複数のブラウザを開けることを考えるとjavascriptでランダムなIDを作ったほうがよさそうです。それから__lzeventはnullだとreceiveEventメソッドが呼ばれないのでこれも設定する必要があります。
ってことでターゲットswfファイルとh.swfファイルを使ってデータを送信するサンプルです。
http://www.asahi-net.or.jp/~ya5m-kwbr/hash4/useFlashVarsEncodeURIUnEscapeMultiGateway.html
下のボタンを押すとh.swfが埋め込まれて、そのタグも見れるようにしました。「onidle: い」の他に、ちゃんと「onval: い」が表示されてます。
ポイントはまずユニークなIDをつくり
connuid = Math.floor(Math.random() * 10000);
それを使ってターゲットのSWFファイルを読み込みます
fo = new SWFObject("unescape_hash.lzx.swf", "lzapp", "500", "150", "6", "#FF6600"); ... fo.addVariable("__lzhistconn",connuid);
そして値を渡すときにはh.swfを読み込みます。
gw = new SWFObject("h.swf", "gw", "1", "1", "6", "#FF6600"); gw.addVariable("n", encodeURI("val")); gw.addVariable("v", encodeURI("い")); gw.addVariable("__lzevent",encodeURI("1")); gw.addVariable("__lzhistconn",connuid); gw.write("gateway");
大きさは必要ないので1とかで構いません。また変数名はnで、値はvで送信します。それから__lzeventはnullにならないように適当な値を入れておきます。最後にターゲットに設定したユニークなIDと同じものを__lzhistconnに設定したら出来上がりです。
蛇足ですがFlash Java Script Integration KitのJavaScriptFlashGateway.swfもh.swfと同じような仕組みでLocalConnectionを使ってデータを渡しています。
http://www.ark-web.jp/blog/archives/2006/02/javascriptflash_1.html
という訳でJavaScriptからOpenLaszloのFlashへデータを送信するところについてはこんなところでしょうか。
あまり長くなったので、逆のOpenLaszloのFlashからJavaScriptへというパターンはまたにします。