はじめてのNode.js:Node.jsのイベントシステムを知る
Node.jsがWebブラウザのJavaScript実行環境と異なるのは、関数やクラスが定義された「モジュール」が利用できる点と、「イベント」と呼ばれる機構を多用する点、そして対話的な実行環境であるREPLが備えられている点だ。Node.jsに初めて触れるユーザーに向け、これらの機能について紹介しよう。
【連載】はじめてのNode.js
- 第1回:Node.jsのイベントシステムを知る
- 第2回:Node.js内でバイナリデータを扱うための「Buffer」クラス
- 第3回:Node.jsアプリケーションのデバッグ
- 第4回:マルチプロセスアプリケーションを作成する
本記事について
本記事は、3月13日にソフトバンク クリエイティブより発売された書籍「はじめてのNode.js -サーバーサイドJavaScriptでWebアプリを開発する-」から、「第7章 Node.jsアプリケーションのデバッグ方法」の一部を抜き出し再構成したものです。
大型本: 384ページ、価格:3,045円(税込)、ISBN: 978-4797370904
Node.jsでのWebアプリケーション実行モデル
PHPやPerlなどの言語でWebアプリケーションを実装する場合、クライアント(Webブラウザ)とのやり取りはApache HTTP ServerなどのWebサーバーが行い、プログラムはWebサーバー経由で実行される形が多い。いっぽうNode.jsの場合、Node.js自体(正確にはNode.jsに含まれるWebサーバーモジュール)が直接クライアントとのやり取りを行う。そのため、別途Webサーバーを用意する必要はなく、Node.jsだけでWebアプリケーションが完結する(図1)。
たとえば次のコードは、Node.jsで実装したシンプルなWebアプリケーションだ。
// httpモジュールを読み込む var http = require('http'); // http.Serverクラスのインスタンスを作成する var server = http.createServer(); // requestイベントハンドラを定義する server.on('request', function(request, response) { // コンソールにリクエストされたURLを出力 console.log(request.url); // 200(OK)レスポンスと「Content-Type: text/plain」ヘッダを送信 response.writeHead(200, {'Content-Type': 'text/plain'}); // 「hello 」という文字列とともにリクエストURLを送信する response.end('hello ' + request.url); }); // 8080番ポートで待ち受けを開始する server.listen(8080, 'localhost');
このコードをREPL上で実行すると、次のように出力される。
> var http = require('http'); undefined > var server = http.createServer(); undefined > server.on('request', function(request, response) { ... console.log(request.url); ... response.writeHead(200, {'Content-Type': 'text/plain'}); ... response.end('hello ' + request.url); ... }); { connections: 0, allowHalfOpen: true, _handle: null, httpAllowHalfOpen: false, _events: { connection: [Function: connectionListener], request: [Function] } } > server.listen(8080, 'localhost'); { connections: 0, allowHalfOpen: true, _handle: null, httpAllowHalfOpen: false, _events: { connection: [Function: connectionListener], request: [Function] } } >
Node.jsの対話的実行環境(REPL)
Node.jsには、対話的にJavaScriptコードを実行できる対話型評価環境(Read Eval Print Loop、REPL)が用意されている。REPL上では手軽にコードを実行できることから、簡単なテストやデバッグなどに有用だ。REPLはコンソールで「node」コマンドを実行することで起動できる。REPL上では変数の操作や、関数呼び出しを含む任意の式の実行、functionキーワードを使った関数の実行などが行える。たとえば次の例は、変数fooに「bar」という値を代入している。
> foo = 'bar'; 'bar'
この例の場合、戻り値は代入した文字列である「bar」となっていることが分かる。
この状態で「http://localhost:8080/」にWebブラウザでアクセスすると、図2のように「hello /」というテキストが表示される。
また、このときREPL環境には次のような文字列が表示される。
> / /favicon.ico
アクセスするURLを変えると、表示される文字列も変化する。たとえば「http://localhost:8080/hoge」にアクセスすると、Webブラウザには「hello /hoge」という文字列が表示され、コンソールには「/hoge」という文字列が表示される。
このWebサーバーは、REPL上でほかの操作を実行しても動作し続ける。Webサーバーを終了するには、REPL上で「server.close()」を実行する。
> server.close(); { connections: 0, allowHalfOpen: true, _handle: null, httpAllowHalfOpen: false, _events: { connection: [Function: connectionListener], request: [Function] } }
もちろん、REPLを終了することでもWebサーバーは停止する。
リスト1のコードは非常に短いコードだが、ここにはモジュールの読み込みやイベントのハンドリング、非同期実行といった、Node.jsプログラミングにおいて特徴的な処理が含まれている。以下ではこのコードを使い、Node.jsプログラミングにおいて押さえておくべきこれら処理について説明していこう。