クロスドキュメントメッセージングやWebSocketを使ってみる
![](https://thinkit.co.jp/sites/default/files/styles/main_image_730x/public/main_images/3542_main_7.png?itok=fJXy53XM)
messageイベントオブジェクトのプロパティは、以下の通りです。
表2:messageイベントオブジェクトの主なプロパティ
プロパティ | 概要 |
---|---|
data | 受信データ |
origin | 送信元のオリジン |
source | 送信元ページ |
重い処理によるブラウザの応答停止を回避する - Web Workers
Web Workersは時間のかかる処理をブラウザのUIとは別の部分で動作させる仕組みです。時間のかかる処理をUIの部分と同じスレッドで実行すると、その処理の最中はブラウザが応答しなくなってしまいます。Web Workersはこれを解消する機能です。Web Workersはリモートサイト間のコミュニケーションではありませんが、他のコミュニケーション系APIと同様にpostMessageとmessageイベントを使用するため、ここで紹介しています。
![]() |
図3:Web Workers(クリックで拡大) |
時間のかかる計算を実行するサンプル
以下のサンプルは、上部のテキストフィールドに、整数を入力して、計算ボタンを押すと、下のフィールドにその整数の素因数分解がJavaScriptの数式の形式で出力されるというものです。Worker不使用のサンプルとWorker使用のサンプルを作成して比較しました。
![]() |
図4:Worker不使用のサンプルでは応答が止まってしまう(クリックで拡大) |
Workerを使用しないサンプルではブラウザの応答が止まってしまい、ウィンドウにアクセスしようとすると強制終了するかを問うダイアログが表示されます。
![]() |
図5:Worker使用のサンプルでは計算中もウィンドウにアクセス出来る(クリックで拡大) |
一方、Workerを使用したサンプルでは計算中も情報の表示や、ウィンドウへのアクセスができます。
Worker不使用サンプル「HTML5_4_sample3_1.html」も処理はほとんど同じなので、コードは割愛します。ダウンロードをご参照ください。以下ではWorkerを使用するサンプルのみ説明します。
[サンプル]素因数分解をWorkerで演算するサンプル(HTML5_4_sample3_2.html)
//Workerオブジェクトを作成、バックグラウンドで動かすJavaScriptを指定 ・・・(1) var worker = new Worker("HTML5_4_sample3.js"); //Workerの開始 function startWorker(){ var t1 = document.getElementById("t1"); //postMessageでWorkerに処理を開始させる ・・・(2) worker.postMessage(t1.value); var t2 = document.getElementById("t2"); //処理の間、計算を待たずにGUI部分の処理もできる ・・・(3) t2.value = "バックグラウンドで計算中・・・"; var button = document.getElementById("recalculation"); button.disabled = true; } //Workerが結果を返した時の処理を登録 ・・・(4) worker.addEventListener("message",displayResult,true); //Workerが結果を返した時の処理 function displayResult(e){ //テキストフィールドに結果データを表示 ・・・(5) t2.value = e.data; var button = document.getElementById("recalculation"); button.disabled = false; } //(HTML部分) <h1>Web Workersを使用するサンプル</h1> <h3>素因数分解</h3> <form name="f1" id="f1"> 整数を入れてください:<input type="text" id="t1" size="15" value="10000000000001"> <!-- 計算ボタン --> <input type="button" value="Workerを使用して計算" onclick="startWorker();" > <br> 計算結果:<input type="text" id="t2" placeholder="結果" size="50"> <!-- 検算用ボタン --> <input type="button" id="recalculation" value="検算" onclick="alert(eval(t2.value));" ><br> </form>
- (1) 実際にブラウザのバックグラウンドで処理をするワーカーをJavaScriptから起動するには、Workerオブジェクトを使用します。コンストラクタの引数には、バックグラウンドで動かしたいJavaScriptファイルを指定します。
- (2) 処理は、postMessageメソッドで開始します。引数に入力値を設定します。
- (3) このように、postMessageメソッドでWorkerに処理を渡した後、結果を待つ間もUIの操作が可能です。
- (4) Workerから計算結果を受け取った場合の処理を、messageイベントハンドラに登録します。
- (5) 結果はmessageイベントオブジェクトeのdataプロパティでアクセス出来ます。
[サンプル] Workerに処理させる計算ロジック(HTML5_4_sample3.js)
//メッセージ受信のハンドラ ・・・(1) onmessage = function (e){ var product=""; //引数の代わりにe.dataに入力データが入っている ・・・(2) var j = eval(e.data); if (j <= 1){return integer}; var k; for(k=2; k <= j; k += (k>2) ? 2 : 1){ if (j % k == 0){ var m = 0; while(j>1 && j % k == 0){ j /= k; m++; } if(j>=1){ product += (product.length>0) ? "*" : ""; product += (m>1) ? "Math.pow("+k+","+m+")" : k; } } } //returnの代わりにpostMessage()で戻り値を返す ・・・(3) postMessage(product); }
- (1) Workerで動かすjsファイルには、UI側からのメッセージを受信した時に発生する、messageイベントのハンドラを記述します。
- (2) 入力値は引数の代わりにmessageイベントオブジェクトeのdataプロパティから取得します。
- (3) 計算や処理の結果を、returnの代わりにpostMessageメソッドで呼び出し元にメッセージを返信しています。
リアルタイムのコミュニケーションを実現する - WebSocket
WebSocketとは、サーバー - ブラウザ間のリアルタイム双方向通信用の規格です。WebSocketでは独自のプロトコルを用います。HTTPと違い、接続の確立が最初だけで同じ接続を使用し続ける事や、サーバー側から応答以外のメッセージの送信が可能となり、HTTPでは実現の難しかったリアルタイムコミュニケーションが可能となります。オンラインゲームの実装などに応用出来る技術です。
![]() |
図6:WebSocket(クリックで拡大) |
WebSocketの実行環境
WebSocketを使用するためにはWebSocketに対応したサーバーが必要です。以下に主な対応サーバーを挙げています。
表3:WebSocketに対応した主なサーバー
名前(サイト) | 概要 | サーバーアプリ記述言語 |
---|---|---|
Jetty (http://www.eclipse.org/jetty/ ) | Javaで作成されたWebサーバー | Java |
jWebSocket Server (http://jwebsocket.org/) | Javaで作成されたWebサーバー | Java |
libwebsockets (http://git.warmcat.com/cgi-bin/cgit/libwebsockets/) | C言語用Websockets Serverライブラリ | C |
SuperWebSocket (http://superwebsocket.codeplex.com/) | .NET用WebSocket Server | C#,VB.NET |
Apache+pywebsocket (http://code.google.com/p/pywebsocket/) | WebSocket server/Apache用WebSocket機能拡張 | python |
node.js+Socket.IO (http://socket.io/) | JavaScript用Webサーバー(node.js)とそのWebSocket機能拡張 | JavaScript(WebSocket非対応ブラウザも考慮されている) |
WebSocketプロトコルの仕様は、2011年12月11日のRFC 6455に至るまでの草案の時から公開されていましたが、何度も改訂されていました。その結果、ブラウザ、サーバーとも実装されているプロトコルが一貫していません。
hybi-xxとは、各草案の名称「draft-ietf-hybi-thewebsocketprotocol-xx」の略で、xxは改訂番号です。例えば、hybi-00とhybi-10には互換性はありません。主な、改訂とブラウザの実装の対応状況を以下の表にまとめました。
表4:ブラウザのWebSocketプロトコル対応状況
IE9 | Chrome18 | Firefox11,12 | Opera11.62 | Safari5.1.5 | |
---|---|---|---|---|---|
hybi-00 | × | ○ | × | ○(*) | ○ |
hybi-10 | × | ○ | ○ | × | × |
RFC 6455(hybi-17) | × | ○ | ○ | × | × |
(*)設定が必要。有効にするにはアドレスバーから「opera:config#Enable%20WebSockets」と入力して、設定画面を開いてチェックボックスをオンにして保存する。 |
サンプルでは、hybi-10に対応したサーバーを使用するために、ChromeとFirefoxのみで確認しています。
サーバーは、nodejs.org(http://nodejs.org/)のWindows版node v0.6.15とnodeモジュールのWorlize/WebSocket-Node1.0.3で確認しました。nodeはサーバー側のコードをJavaScriptで実装出来るWebサーバーです。追加機能がモジュールの形で提供されています。WebSocket対応化モジュールはWebSocket-Nodeの他に、Socket.IO、websocket-serverなどがあります。Socket.IOが最も実装が進んでいて高機能ですが、ブラウザ側コードもSocket.IO独自のものとなってしまうために、今回はWebSocket-Nodeを使用しました。
◆◇◆◇ コラム:Windows版nodeとWebSocket-Nodeのインストールと起動の手順 ◆◇◆◇
- nodejs.orgのサイトからインストーラ(msiファイル)をダウンロードしてインストール
- Program Filesフォルダのnodejsにnode.exeやnpm.cmdがインストールされている事を確認(npmはnodeのパッケージ管理ツールです。インターネットに接続されている環境ではコマンド1つでnodeモジュールをインストール出来ます。)
- コマンドプロンプトを開き「npm install websocket@1.0.3」を実行(最新版は1.0.4だがエラーになるため)
- nodejs\node_modulesフォルダにwebsocketがインストールされている事を確認
- 「node app.js」(app.js:サーバーコードの記述されたJavaScriptファイル)でサーバー起動
HTML5のコミュニケーション機能サンプル
連載バックナンバー
Think ITメルマガ会員登録受付中
全文検索エンジンによるおすすめ記事
- Socket.IOを使ってNode.jsでリアルタイムWebアプリを開発する
- サンプルのプログラムコード解説
- クッキーより便利になったブラウザ標準ストレージ- Web Storage
- HTML5のドラッグ&ドロップAPI、File API、Web Storage
- スマホアプリ開発にも便利な位置情報API- Geolocation API-
- デスクトップアプリライクな操作性を実現するドラッグ&ドロップAPI
- プラグインは要らない!音声/動画対応したHTML5- / 要素
- 変数につまずくのはもうやめたい!
- JavaScriptでローカルファイルを自在に操る- File API
- 動画・音声のブラウザ対応状況、canvasによる描画