noVNC は、VNCクライアントで、 HTML5 WebSockets, Canvas そして JavaScriptを使って実装されている。InfoQ、は、 Joel Martin氏と、 noVNCと HTML5アプリケーションの開発経験について、少しばかり、Q&Aを持った:
InfoQ: Joelさん、noVNCのアーキテクチャの全体像と様々なコンポーネントがどのように、いっしょになっているのか,教えてください。
Joel: noVNCのアーキテクチャは、6つの主要なコンポーネントからできています:
- コアの VNC/RFB実装: このコンポーネントは、すべてのRFBプロトコルの情報をカプセル化していて、他のすべてを動かす、主要なステートマシンです。
- Canvas抽象層: このコンポーネントは、 HTML5 CanvasAPIを抽象化した層を提供してます。またCanvasのフィーチャを検知して、完全な HTML5 Canvasスペックを持っていなかったり、中途半端な実装をしているブラウザを迂回します。
- ユーザーインタフェース: すべてのHTML DOM のやりとり(Canvasは除いて)は、ここでカプセル化されます。このコンポーネントによって、接続/切断ボタン、設定そして状態のフィードバックのようなページ コントロールを描画します。 noVNCの私の設計目標の1つは、既存のサイトに簡単に入り込むことなので、このコンポーネントは、オプションです。
- ユーティリティ: noVNCによって使われる様々な一般的なルーチンや拡張機能がここに含まれています。例えば、Javascript の配列を拡張して、キュー、クロス-ブラウザなイベント処理、デバッグ/ロギングに使えるように、もっとそれらを便利なものにしています。
- WebSocketsのフォールバック:規格に非準拠な、大抵のブラウザは、ネイティブにWebSocketをサポートしていないので、私は Flash (flex)エミュレータ をそのようなブラウザ用に開発しました。元のプロジェクトを拡張して,WebSocket暗号化をサポートしました。
- WebSockets から TCP へのプロキシ:WebSocketの標準は、純粋なTCPソケット実装ではありません。HTTPのようなハンドシェイクで最初のコネクションを確立し、その後、全てのフレームは、0(ゼロ)バイトで始まり、255バイトで終ります。VNCサーバーがWebSocketサポートを実装するようになる(私は、そうなって欲しいのですが)までは、WebSocketから標準のTCPソケットに変換するプロキシが必要です。私は、これを一般的なプロキシとして( python とCの両方で)実装しました。これは、WebSocketを使って開発する他の開発者には、役立つはずです。
InfoQ: HTML5アプリケーションの開発で一番大変だったのは,何ですか?開発者が、一番注意を払わなければならない落とし穴は、なんですか?
Joel: 一番大変だったのは、 HTML5をサポートしていなかったり、 HTML5のフィーチャが限られていたり、動きがまずかったり、フリーズするブラウザに、フォールバックのサポートを入れることに関してでした。例えば、 Chrome 5 とSafari 5は、ネイティブなWebSocketをサポートをしていますが、 Firefox とOpera の現在のバージョンは,していません。これらのブラウザの古いバージョンの中には、もっと最近の canvasのピクセル操作APIを持っていないものがあります(更に悪いことには、 Arora 0.5のようにフリーズするものがあります)。Internet Explorer には、WebSocketを組み込んでいるものがありませんし、もっと基本的な canvasのサポートすら組み込んでいません(IE 9 のプレビュー版は、準備的にcanvasをサポートしています)。他に難しかったのは、複数のブラウザにまたいで、パフォーマンスの最適化をすることでした。それぞれのブラウザには、違ったパフォーマンス特性があり、同じブラウザでもリリース間で変わるんです(同じブラウザでもOSが違うと、また違ったりします)。私は、まさにこの分野こそが、ブラウザ検知が生きてくるところだ,と思います。
InfoQ: どんなツール類を使ったのですか?現在の開発ツールは、 HTML5アプリケーションを作るのに充分強力だと思いますか?どんな新しいツールが欲しいでしか?
Joel: 私の開発環境には、本当に最小限のものしかありません。私は、コード編集に、Linux上でvim(たくさんの拡張機能をつけて)を使ってます。私は、デバッグやプロファイリングに、Firefoxで firebugを、そしてChromeに組み込まれている開発ツールを非常に良く使います。CrockfordのJSLint を物凄く使って、 Javascriptコードをいつもきれいにしています。
firebug やChromeのプロファイリング ツールが、関数レベルよりもっと細かい粒度で、フィードバックしてくれたら,と思います。それとプロファイラには、コードのどの部分が、ガーベッジコレクションに、最も関わっているのかを教えてくれる、深い分析を提供して欲しいですね。今、大きなパフォーマンスのボトルネックの1つであるガーベッジコレクションに、突入したばかりの段階で、 noVNCコードを最適化する直前です。
私が欲しい新しいツールは、コード分析ツール( JSLintと同じようなやり方で)で Javascriptのコードベースをスキャンして,きれいに、ブラウザのサポートを示すテーブルを生成して欲しいです。私がイメージする結果は、トップにコードで使われるフィーチャのリストが並び、主なブラウザとバージョンが左に並びます。各セルが、コードのフィーチャの使い方が各ブラウザ/バージョンでサポートされているかどうかを示してくれるわけです。そうなれば、たくさんのブラウザでテストする必要がなくなり、また間違いなく開発中でも、正しくコーディングしているかどうかを知るのに役立ちます。理想的には、Javascript コードがそのフィーチャために、適切な検知/ワークアラウンド(回避策)をやっているかも、スキャナが検知してくれるといいのですが。
InfoQ: あなたが克服しなければならなかった現行のスペックや実装上の大きな限界は,何でしたか?
Joel: 幸いにも、この分野は、スペックが非常に良いのです。
RFB (VNC)プロトコルは、 http://tigervnc.org/cgi-bin/rfbprotoに、はっきりと文書化されています。
このサイトは、 Javascriptの素晴らしいリファレンスを提供しています(どのブラウザのどのバージョンが各フィーチャをサポートしているかも載ってます): http://www.hunlock.com/
私が知っている範囲で、どのブラウザがどのフィーチャ(HTML5やもっと)をサポートしているかをまとめている最高のサイトは、 http://caniuse.com/です。http://quirksmode.org は、どのバージョンがどのAPIをサポートし、それらの制限をどのように回避するかについて、詳細な情報を提供している貴重なサイトです。私がこれまでに、乗り越えなければならない最も大きなブラウザの制限は、ネイティブな、ブラウザ間のWebSocketサポートが無いことです。これは、最近の標準でまだ変わっていますが、急速に採用されています。Chrome 5 と Safari 5 のwebキットには、すでにありますし、 iPhoneもまもなくサポートするでしょう。 Firefox 4もおそらく採用するでしょうし、Opera だって絶対にいつかは、実装しますよ。最も大きな疑問は、 IE 9チームがサポートすることを決めるかどうかですね。
既に言いましたように、ネイティブでサポートしていないブラウザをサポートするのにFlash WebSocketエミュレータを使ってます。 Flash (ActionScript) コードを拡張したり、その中のバグを修正したり、回避するのは、大変な作業です。 JavascriptとFlashを繋ぐのも非常に頭の痛いことです。 Adobe は、 FABridge(エミュレータが使っている)を提供してますが、これは,遅くて、大きくそして、デバッグが難しいです
IE9が完全な(しかも高速な)Canvasサポートをする、というニュースにワクワクする一方で、ネイティブなCanvasサポートしていないIEの古いバージョンをこれからもサポートし続けるつもりです。それらは,非常に普及してますからね。私が今検討している2つの選択肢は、 explorercanvas と fxcanvasです。Explorercanvas は、 Javascriptライブラリで、IEのVMLサポートの上で、 canvas APIを作ります。 fxcanvasは、 canvasのFlash による実装です。しかし,両方の選択肢とも大きな問題があります。 Explorercanvasは、ピクセル操作をサポートしません(VMLがラスターではなくベクターのためです)。そして fxcanvasは、 canvasもどきのAPIを供給するだけですし、また重要な非同期処理上の問題を抱えています。不幸にして、 IE 6, 7 そして 8のJavascript エンジンは、他の現在のブラウザと比べて非常に遅いので、 canvas エミュレーションをやったら、使えないことが判明するかもしれません。そうなったら私は、皆さんに Chromeのフレームを勧めるだけになるかもしれません。
InfoQ: noVNCプロジェクトの将来の計画は、何ですか?
Joel: 私が今もっともワクワクしているのは、何人かの QEMU/KVMの開発者(Google Summer の Code Studentを含んで) と仕事して、ブラウザの描画にもっと最適化した、新しいVNCエンコーディングを設計することです。この新しい VNC/RFBエンコーディングは、イメージデータを PNGフォーマットで転送します。ロスレスのイメージデータ用の高圧縮( tight encodingに比べて)に加えて、PNGデータストリームを非常に小さなデコード処理でブラウザで簡単にレンダリングできます( tight encodingとは違います)。
WebSockets から TCPソケットへのプロキシを必要とするのが、 noVNCをもっと広く使ってもらう時の障害になってます。私は、VNCサーバーにWebSocketサポートが加えられることを望んでいます。私は個人的には libvncserver (いくつかの違ったVNCサーバーを作るのに使われている)と QEMU/KVMに注目しています。他のVNCクライアントにWebSocketサポートを加えることも、実用的だと思います。WebSocketプロトコルは、Webサーバーによって容易にサポートでき,プロキシできるように設計されています(だから、最初がHTTP互換のハンドシェイク)。このことが、ファイアウォールの扱いという、VNCの歴史的な問題の1つを解決するのに役立つでしょう。
私がプロジェクトを "noVNC"と名付けた理由の1つが、 RDP, NX そして Red Hatの Spiceプロトコルのような他の「仮想ネットワークコンピューティング」プロトコルの実装も見たかったからです。
もし iPhone がネイティブなWebSocketサポート(明らかに Flashフォールバックは問題外です)を加えたら、その時は、 iPhone上で、 noVNCを走らせたいですね。私が付け加えたい1つのフィーチャは、一般的に有益ですが、スマートフォンでのサポートでは,重要です。それは、ビューポートと/あるいは拡大・縮小のサポートです。そして、 Googleよ、聞いているなら、無料の Androidフォーンは、 Android上でnoVNCを 動かすための素晴らしいインスピレーションなりますよ。 :-)
同じようなアプローチが、プロジェクト Guacamole でも、とられている。これも HTML5 VNCビューアで、Java で書かれたサーバーサイドのプロキシを使っている。現在のバージョンは、ネイティブのVNCとほぼ同等のレスポンス スピードで 、HTML5 canvasタグをサポートしているどのブラウザでも動いている、とのことである。
HTML5 と Rich Internet Applications(リッチ インターネット アプリケーション)についてもっと知りたければ、まさしくこのInfoQで!