« Gitのcore.editorにEmacsを指定する試行錯誤(Macの場合) | メイン | Server.addHandlerの無くなったJetty7で複数のHandlerを追加する方法 »

WebSocketを使ってリモートデスクっぽいVNCっぽいWebSocketRemoteというものを作ってみました

(2010/10/07 追記:デモを作成しました。)
(2010/04/09 追記:タイトル内のVNCをSVNと間違えていたのを修正しました。)
次世代のWebの規格としてWebSocketというものがあります。WebSocketは、AjaxでもCometでもないサーバ-クライアント間の新しい通信方法です。通常のWebアクセスや、Ajax・CometはHTTPを使用していますが、WebSocketはHTTPではありません。接続のたびに接続のリクエストが発生するHTTPと違い、WebSocketはとても高速で、同時に複数の接続も可能となっています。遅延も小さく比較的容量の大きいデータも高速に転送できるため、リモートデスクトップのようなものが作成できないかと思い、WebSocketRemoteというものを作ってみました。ブラウザには、プラグインやFlash、Javaアプレット等は一切不要となっています。
作成の経緯
以前、「Ajax Mouse」というものを作成しました。
一応動作するのですが、XMLHttpRequestを使用しているため、遠隔操作に利用するには遅過ぎました。Javaのサーバの知識もJavaの高速化の知識もなかったため、改善を諦めていました。しかし、HTML5に関連した技術であるWebSocketというものを利用すれば、実用レベルまで引き上げることができるのではと考えました。ところが、WebSocketは現時点ではまだドラフト版のためか、Google Chromeでしか使用できません(SafariやFirefoxの次のバージョンで実装されるようです)。iPhone/iPod touchではなく、デスクトップ上のブラウザで実行するのだから、ついでに画面も転送してリモートデスクトップやVNCのように使えるようにならないかと考えました。
技術
クライアント側に要求されるのはWebSocketが使えるブラウザだけです。サーバ側は、JavaからGUIを操作できるRobotというクラスと、Java実装のサーバでWebSocketを実装しているJettyを利用しています。
サーバからクライアントへの画像の転送は、「Robotで画面キャプチャ => Base64化 => 分割してWebSocketで転送 => ブラウザ側で連結し表示」と処理しています。クライアントからサーバへのイベントの転送は、「JavaScriptイベント => WebSocketで転送 => Robotで操作」となっています。
転送しているイベントは、現バージョンではマウスの操作だけです。これは、ブラウザ側でキーイベント時のキーがまともに取得できないためです。特に、うまいクロスブラウザへの対応方法が不明のため、他の主要ブラウザがWebSocketを実装するまで保留とします。(文字入力だけであれば、クロスブラウザ対応ができなくもないのですが、カーソル操作もできない可能性があります。)
ライセンス
JettyとApache CommonsのCommons CodecがApache License Version 2.0を採用しているため、WebSocketRemoteもApache License Version 2.0とします。(ただし、JettyはEclipse Public License 1.0とのデュアルライセンスです。)
ダウンロード
GitHubからダウンロードして下さい。現バージョンは「WebSocketRemote-0.0.1-bin.zip」です。(2010/04/08 追記:バージョンは0.0.4に上がっています。)
実行方法
サーバにはJavaVMが必要です。クライアントにはGoogle Chromeをインストールして下さい。サーバとクライアントは別の端末を使用して下さい。(同一の端末で実行すると、ブラウザのウィンドウ上にカーソルがのった瞬間に、カーソルが別の位置に移動してしまいます。)
サーバとクライアント間は有線LAN環境をお勧めします。(無線LANでも動かないことはないのですが、とても実装に耐えるような速度ではありません。)
ダウンロードしたWebSocketRemoteを解凍します。サーバ側でWebSocketRemoteを実行して下さい。
Windows用にexeファイルが、Mac OS X用にはdmgファイル内にappファイルがあります。Linuxの場合はjarファイルを実行して下さい。
クライアントのGoogle Chromeで、「http://[サーバのアドレス]:40320/」にアクセスして下さい。(現バージョンではポート番号は固定です。)
クライアントのブラウザのウィンドウ内に、サーバのデスクトップが表示され、マウス操作が可能になります。ブラウザのウィンドウよりもサーバのデスクトップ領域が広い場合、カーソル位置にあわせて画面がスクロールします。
セキュリティ
認証等の機能は全く実装していません。WebSocketRemoteを実行していると、他の端末からいつでも画面を表示する事が可能になります。
現時点で未対応の主な機能と問題点
キーボード操作に対応していません。うまい実装方法があれば教えて下さい。
環境がないためマルチディスプレイに未対応です。対応方法は一応考えています。モニタもあります。でも、ケーブルがありません。ケーブル購入後に実装する予定です。(2010/04/08 追記:バージョン0.0.3でマルチディスプレイに対応しました。)
実装方法が悪いのか、技術的にそういうものなのかはわかりませんが、サーバ側のCPU占有率が90%にもなります。(2010/04/08 追記:バージョン0.0.4で、画像を処理が重いPNGから比較的処理が軽いJPEGに変更することで60%まで落としました。次に重い処理はキャプチャのため、これ以上処理を軽くするのは困難かもしれません。)(2010/04/10 追記:バージョン0.0.5で、キャプチャの処理時間に応じてsleepに指定する時間を変動するようにしました。この修正によりCUP占有率が35%前後になりました。)
謝辞
WebSocketRemoteのアイディアを形にできたのは、keisukenさんのおかげです。keisukenさんには、不足している多くのスキルの補って頂きました。本当にありがとうございます。

コメント (1)

Hiroshi Ichikawa [TypeKey Profile Page]:

http://d.hatena.ne.jp/Gimite/20090813/1250172818
これを使うと(Flash経由で)Chrome以外のブラウザでもWeb Socketを利用できます。よろしければどうぞ。

コメントを投稿

(いままで、ここでコメントしたことがないときは、コメントを表示する前にこのブログのオーナーの承認が必要になることがあります。承認されるまではコメントは表示されません。そのときはしばらく待ってください。)

Google

タグ クラウド