Archive for the ‘Flex’ Category
flex4のsparkコンポーネントの理解がまだまだなので、メモ。
どうやら、sparkにおいてContainerの基本は、
s:Group
と
s:DataGroup
のようだ。
sparkになって画面表示に関していえば、ContainerとLayoutが分けられた。
(もちろん、利便性のために一緒になっているものもあるが・・・)
Groupはようは、可視コンポーネントを何でも入れてよくて、今までのHBoxや、VBoxのような感じ。
しかし、DataGroupは便利な気がする。
以前のmx:DataGridのように、itemRendererとdataProviderのプロパティを持つ。
従って、dataProviderを使ってデータを提供できる。
そして、そのデータを使ってitemRendererで可視コンポーネントを表示できる。
あとは、ContainerとLayoutが分かれたメリットで、どうそれらを配置していくかを決めていける。
したがって、同じようなデータと部品を規則正しく配置していくのには便利。
たとえば、これを使えばカレンダーコンポーネントみたい物もそれほど難しく作れるだろう。
今日、初めてFlash Builder4を使い始めました。
AIR2.0もリリースされたことですし、それもインストールして、SecureSocketを使ってgmailに接続できるかを確認するのに、
サンプルもFlex4のSparkで書き直すことにしたのですが・・・・
まだ、慣れません。
何が慣れにくいかって、s:XXXX と mx:XXXXX が両方あるあたりですね。
混在できるのは、すでにあるものの移行をしつつ、新しい開発と考えるといいのかもしれませんが、
理解ということになると、
昔のXXXはYYYになります。
というようになれば、理解(あきらめの意味も含めて)がしやすく感じます。
TabNavigatorって、何になるんだ?ってわかりませんでした。今のところ。
工夫しだいで、Sparkだけでもできるのかもしれませんが・・・
mx:TabNavigator は s:TabNavigator
と、なっていれば、たとえ、実体が同じでも使いやすと思うのは私だけでしょうか?
<mx :TabNavigator width="100%" height="100%" resizeToContent="true"> <s :NavigatorContent /> </mx>
って、混じるのはちょっと異物を見ていると感じてしまうのは、
まだ、慣れていないからだけなのでしょうか・・・・
まあ、まださわり初めですので、利点が勝っていることが実感できれば、気にならなくなるかもしれません。
しかしながら、生まれて初めてIDEのVisualEditor(デザイン)の方を使ってしまいました。
どちらのコンポーネントを使うことをIDEは望ましいと思っているのかも含めての意味もありますが、使ってしまいました。
今まで、Flex Builder3でも、Eclipseや、VisualCafe(なつかしい・・・)でも、C++Builderでも使ったことも、使おうと思ったこともない機能なのですが・・・・
マウスで、画面イメージを作っていくことなんて・・・
要するにAMFのデータをJava側で処理する方法です。
しかし、httpのプロトコルを使っての話ではないです。
たとえば、AMF3のデータをBase64してそれを、再度Javaで復元するという感じです。
具体的には、XMLSocketを通じてやりとりをしてみます。
XMLSocketのサーバについてはこちらにて多少説明してあります。
httpプロトコルを使わないのは、Flash側に簡単にpush配信ができるからです。
まあ、ずーとコネクションを張っていますから、そりゃできますよね。
でも、http通信を使ってもクライアント側にpush配信できるソリューションがあるので、
どうやっているのかなーと思ったら、keep-aliveでずーとコネクションを張りっぱなしにしてトンネルするのですね。知りませんでした。
(この方法、XMPPを見ていて知りました。)
そんなことをやろうとも思いもしませんでしたが、確かに、httpサーバを作る側になったときに、
keep-aliveでセッションを張られたときにいったいいつコネクションを切ればいいのかというのが悩みの種という思いをいただいた記憶がありました。
idleタイムとかでやるしかないのでしょうが・・・・めんどくさいです。でもサーバですからね。。。。
それと、PHPなんかには、AMF3のデータを処理するライブラリがたくさんあるのに、Javaにはないのかなーと思っていたら、
本家(Adobe)から出しているので、ないのですね。
さて、それではJavaのライブラリの取得方法は
本家から、BlazeDSのBinaryをダウンロードしてきます。
次に、blazeds.warがありますから、これがZIP圧縮されていますので解凍して、
\blazeds\WEB-INF\lib
にある
flex-messaging-common.jar
flex-messaging-core.jar
を取得して、これをJavaのクラスパスに設定できるようにしておいてください。
さて、AS3側の処理です。簡単なのでかなりはしょっていますが、流れを見ていただければ・・・
var sock:XMLSocket = new XMLSocket();
sock.connect(HOST,PORT);
:
public function send(data:*):void{
var bytes:ByteArray = new ByteArray();
bytes.writeObject(data);
var b64:Base64Encoder = new Base64Encoder();
b64.encodeBytes(bytes);
sock.send(b64.toString());
}
のように、どんなオブジェクトでもByteArrayからBase64してXMLSocketへ投げます。これで、as3側はOKです。
次にJava側ですが・・・
再度、XMLSocketのサーバについてはこちらにて多少説明しています、そして、そのソースを再利用しています。
// ここで送られたBase64の文字列をどうにかして取得する。
String request = (String) e.getMessage();
Decoder base64 = new Base64.Decoder();
base64.decode(request);
byte[] data = base64.flush();
ByteArrayInputStream bais = new ByteArrayInputStream(data);
Amf3Input input = new Amf3Input(new SerializationContext());
input.setInputStream(bais);
log.debug("request object:" + input.readObject().getClass());
と、Amf3Inputというオブジェクトを使ってあげればよくて、そこで、readObject()を使えば、オブジェクトが取得できます。
たとえば、AS3のDate型のオブジェクトを渡せば、Javaでは、java.util.Dateの型になるという感じです。
次は、JavaのオブジェクトをAS3側で扱えるようにしてみたいと思います。
昨日の続きであるが、ローカルマシンとの接続はXMLSocketを使うことにしてみた。
とりあえず、これで思うようにできるのか、試してみることにした。
XMLSocketは、AIR以外でも使えるSocket通信だ。
いろいろ、セキュリティ関係はみれていないので、まだまだよくわからないところもあるが・・・
XMLというとなんか、定義されたルールがあるのかと思ったら、
要するに、テキストしか送受信できないSocket通信のようだ。
また、サーバのフレームワークにはnettyを使うことにした。
どうやら、MINAとnettyを作った(ている)人は同じ人らしいが、現在はnettyの方をやっているらしい
ここでは、nettyについて詳しく述べないが、夜にちょっと調べたレベルでも、簡単なサーバが作れる。
実際の受信して、返信するレベルの実装は、こんな感じだ。
(ただ、まだまだ意味がわからず書いているところも多少あるが、どれだけ簡単なイメージかはつかめるかと思う)
package com.coltware.airboost.netty.flash;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jboss.netty.channel.ChannelFuture;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.channel.ChannelPipelineCoverage;
import org.jboss.netty.channel.ChannelStateEvent;
import org.jboss.netty.channel.ExceptionEvent;
import org.jboss.netty.channel.MessageEvent;
import org.jboss.netty.channel.SimpleChannelUpstreamHandler;
@ChannelPipelineCoverage("all")
public class FlashXMLSocketServerHandler extends SimpleChannelUpstreamHandler {
private static Log log = LogFactory
.getLog(FlashXMLSocketServerHandler.class);
@Override
public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e)
throws Exception {
log.debug("channelConnected ... " + e.toString());
e.getChannel().write("hello\0");
super.channelConnected(ctx, e);
}
@Override
public void messageReceived(ChannelHandlerContext ctx, MessageEvent e)
throws Exception {
log.debug(e.getMessage().getClass());
String request = (String) e.getMessage();
log.debug("request: " + request);
String response = "say what!?\0";
ChannelFuture future = e.getChannel().write(response);
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) {
log.warn("Unexpected exception from downstream.", e.getCause());
e.getChannel().close();
}
}
これは、Flashの方から、接続すると、「hello」が返され、何かメッセージを送ると、「say what!?」と返すだけのサーバだ。
少なくとも、これで、merapiのサンプルで書かれていたレベルの基盤はほとんどできてしまっている。
通常、サービスを止める場合には、シグナルを送る(Unix/Linux)とか、管理ポートを開いてそこで、管理コマンドを受けるとかあるが、
私は、JMXを利用した。
後は、送る文字列と送信する文字列をAMFベースにしてしまえばいいわけだ。
ただ、バイナリが送れるかわからないので、そのあたりはbase64してしまえばいい。
また、nettyのいいところは、httpの通信を標準でサポートしているので、httpベースのサーバも簡単に作れるので、
もし、XMLSocketがだめなら、別の通信と、通信プロトコルは好きに定義すればいい。
今まで、リビジョンで管理していましたが、ある程度こなれてきたとも思うので、バージョン 0.5としました。
どうしてVersion 1 ではないかといえば、せっかくなので、Flex4 & AIR2.0 でVersion 1.0 にしようと思っています。
ちなみに、前回のRevision44からの主な変更点(バグ修正)では、
1)長いサブジェクトの場合におかしなサブジェクトになっていた。
2)本文の最後に.(ドット)がついてしまっていた。
を修正しました。
ダウンロードは

