Node.js v0.11.11 マニュアル & ドキュメンテーション


Table of Contents

About this Documentation#

このドキュメントのゴールは、Node.js の API についてリファレンスとしても, 概念的な視点としても,包括的な説明をすることです。 それぞれのセクションは組込のモジュールまたは高水準の概念について記述します。

必要に応じて、プロパティの型やメソッドの引数、そしてイベントハンドラに 与えられる引数などの詳細は見出し直後のリストで与えられます。

すべての .html ドキュメントは、対応する .json ドキュメントを持ちます。 それは同じ情報を同様の構造で表現します。 これは実験的で、ドキュメントをプログラム的に扱いたい IDE や他の ユーティリティのために加えられました。

すべての .html.json ファイルは、node ソースツリーの doc/api/ フォルダにある、対応する .markdown ファイルを基に生成されます。 ドキュメントの生成には tools/doc/generate.js が使われます。 HTML のテンプレートは doc/template.html にあります。

Stability Index#

ドキュメント全体を通して、セクションの安定度に関する目安を見ることが できるでしょう。 Node.js の API はまだ少し変更されます。 それが成熟することにより、ある部分は他よりも信頼できるようになります。 いくつかはそのように証明され、したがって信頼され、それらはおそらく 変更されそうもありません。 その他は新しくて実験的か、危険が知られていたり、再実装が始まっていたりします。

Stability (安定度) を以下のように示します:

Stability: 0 - 廃止予定
この機能には問題があることが知られていて、変更が計画されています。
これに依存しないでください。この機能を使用すると警告が出されるでしょう。
後方互換性を期待すべきではありません。
Stability: 1 - 実験的
この機能は最近導入され、将来のバージョンで変更されるか削除されるかもしれません。
それを試してフィードバックをしてください。
重要なユースケースで使われるなら、node コアチームに教えてください。
Stability: 2 - 不安定
API は安定化の途中ですが、まだ安定していると考えられるほどには
現実世界でテストされていません。
もし合理的なら後方互換性が維持されるでしょう。
Stability: 3 - 安定
API は要求を満たすことがわかりましたが、実装コードをクリーンナップするために
小さな変更が行われるかもしれません。
後方互換性は保証されます。
Stability: 4 - API 凍結
API は実運用で広範囲にテストされており、おそらく変更されることはありません。
Stability: 5 - 固定
深刻なバグが見つからない限り、コードは変更されません。
このエリアの変更を提案しないでください; そえは拒否されます。

JSON Output#

Stability: 1 - 実験的

markdown から作られる全ての HTML ファイルは、対応する JSON ファイルを持ちます。

これは v0.6.12 からの新機能で、実験的です。

Synopsis#

'Hello World' と返答する Node で書かれたWebサーバの例:

var http = require('http');

http.createServer(function (request, response) {
  response.writeHead(200, {'Content-Type': 'text/plain'});
  response.end('Hello World\n');
}).listen(8124);

console.log('Server running at http://127.0.0.1:8124/');

このサーバを実行するには、コードを example.js というファイルに保存し、 node コマンドで実行してください。

> node example.js
Server running at http://127.0.0.1:8124/

このドキュメントの全てのサンプルは同じように実行することができます。

Global Objects#

これらのオブジェクトは全てのモジュールで有効です。 これらのオブジェクトのいくつかは実際はグローバルスコープではなくモジュールスコープです - 注意してください。

global#

  • {Object} グローバルなネームスペースのオブジェクト

ブラウザでは、トップレベルのスコープはグローバルスコープです。 これは、ブラウザではグローバルスコープで var something と定義するとグローバル変数になることを意味します。 Node では異なります。 トップレベルのスコープはグローバルスコープではありません; Node のモジュール内での var something はそのモジュールでローカルになります。

process#

  • {Object}

プロセスオブジェクトです。process オブジェクト の節を参照してください。

console#

  • {Object}

標準出力および標準エラー出力へのプリントに使われます。 コンソール を参照してください。

Class: Buffer#

  • {Function}

バイナリデータを扱うために使われます。 バッファセクション を参照してください。

require()#

  • {Function}

require モジュールを指します。モジュール の節を参照してください。 require は実際はグローバルではなく、各モジュール毎のローカルです。

require.resolve()#

require() の内部でモジュールの位置を検索するために使われます。 モジュールのロードは行わず、ファイル名を解決して返すだけです。

require.cache#

  • Object

モジュールが要求されると、このオブジェクトの中にキャッシュされます。 このオブジェクトからキーと値を削除すると、次にそのモジュールが require されたときにリロードされます。

require.extensions#

Stability: 0 - Deprecated
  • Object

require にファイル拡張子を扱う方法を教えます。

拡張子が .sjs であるファイルの処理を .js と同じにするには:

require.extensions['.sjs'] = require.extensions['.js'];

廃止予定 かつて、このリストは非 JavaScript モジュールを必要に応じて コンパイルし、Node にロードするために使われていました。 しかし実際には、他の Node プログラムを通じてロードしたり、 事前に JavaScript にコンパイルするなど、よりよい方法があります。

モジュールシステムはロックされているので、この機能はおそらく 無くならないでしょう。 しかしながら、それは微妙なバグや複雑さがあってもそのまま放置されるでしょう。

__filename#

  • {String}

実行されているコードのファイル名です。これは解決された絶対パスです。 メインプログラムでは、必ずしもコマンドライン引数で使われたファイル名と 同じではありません。 モジュールの中では、この値はそのモジュールファイルのパスとなります。

例: node example.js/Users/mjr で実行する

console.log(__filename);
// /Users/mjr/example.js

__filename は実際はグローバルではなく、各モジュール毎のローカルです。

__dirname#

  • {String}

現在実行されているスクリプトが存在するディレクトリの名前です。

例: node example.js/Users/mjr で実行する

console.log(__dirname);
// /Users/mjr

__dirname は実際はグローバルではなく、各モジュール毎のローカルです。

module#

  • {Object}

現在のモジュールへの参照です。 module.exports は、モジュールが公開して require() を通じて利用可能になる ものを定めるために使われます。

module は実際はグローバルではなく、各モジュール毎のローカルです。

より詳しくは モジュールシステムのドキュメント を参照してください。

exports#

module.exports への参照です。 いつ exports を使い、いつ module.exports を使うかの詳細は モジュールシステムのドキュメント を参照してください。

exports は実際はグローバルではなく、各モジュール毎のローカルです。

より詳しくは モジュール を参照してください。

setTimeout(cb, ms)#

少なくとも ms ミリ秒が経過した後、コールバック cb を実行します。 実際の遅延は OS のタイマ分解能やシステムの負荷など外部要因に依存します。

タイムアウト値は 1~2,147,483,647 の範囲内でなければなりません。 もし値がこの範囲外だった場合は 1 ミリ秒となります。 大雑把に言って、タイマは 24.8 日を越えることはできません。

タイマを表現する不透明な値を返します。

clearTimeout(t)#

setTimeout() によって以前に作成されたタイマを終了します。 コールバックは実行されなくなります。

setInterval(cb, ms)#

ms ミリ秒ごとにコールバック cb を繰り返し実行します。 OS のタイマ分解能やシステムの負荷など外部要因によって、 実際のインターバルが異なるかもしれないことに注意してください。 それは決して ms より短いことはありませんが、より長いことがあります。

インターバル値は 1~2,147,483,647 の範囲内でなければなりません。 もし値がこの範囲外だった場合は 1 ミリ秒となります。 大雑把に言って、タイマは 24.8 日を越えることはできません。

タイマを表現する不透明な値を返します。

clearInterval(t)#

setInterval() によって以前に作成されたタイマを終了します。 コールバックは実行されなくなります。

タイマー関数はグローバル変数です。タイマー を参照してください。

console#

Stability: 4 - API Frozen
  • Object

標準出力と標準エラーに出力するためのものです。 ほとんどのブラウザで提供されているコンソールオブジェクトと同様ですが、 出力は標準出力か標準エラー出力に送られます。

コンソール関数は出力先がターミナルまたはファイルの場合は同期 (早すぎる終了によりメッセージが失われるケースを防ぐため)、 パイプの場合は非同期 (長時間ブロックすることを防ぐため) です。

つまり、以下の例では標準出力はノンブロッキングですが、 標準エラー出力はブロッキングです:

$ node script.js 2> error.log | tee info.log

通常の使用では、膨大な量のデータを記録するのではない限り、 ブロッキング/ノンブロッキングのどちらなのかを心配する必要はありません。

console.log([data], [...])#

改行を伴って標準出力へプリントします。 この関数は printf() のように複数の引数を受け付けます。

console.log('count: %d', count);

最初の引数文字列からフォーマット要素が見つからなかった場合は、 util.inspect が各引数に使われます。 より詳細は util.format() を参照してください。

console.info([data], [...])#

console.log と同じです。

console.error([data], [...])#

console.log と同様ですが、標準エラー出力にプリントします。

console.warn([data], [...])#

console.error() と同じです。

console.dir(obj)#

util.inspect を使って obj を文字列化した結果を標準出力にプリントします。 この関数はあらゆるオブジェクトのカスタム inspect() 関数をバイパスします。

console.time(label)#

タイマを作成します。

console.timeEnd(label)#

タイマを終了し、結果を出力します。例:

console.time('100-elements');
for (var i = 0; i < 100; i++) {
  ;
}
console.timeEnd('100-elements');

console.trace(label)#

現在のスタックトレースを標準エラー出力にプリントします。

console.assert(expression, [message])#

assert.ok() と同様に、もし expressionfalse に評価されると、 message を持つ AssertionError がスローされます。

Timers#

Stability: 5 - Locked

全てのタイマ関数はグローバルです。 このモジュールを使うために require() をする必要はありません。

setTimeout(callback, delay, [arg], [...])#

delay ミリ秒が経過した後で、 callback が一度だけ実行されるようにスケジュールします。 clearTimeout() で使うことができる timeoutId を返します。 オプションとして、コールバックへの引数を渡すこともできます。

コールバックが正確に delay ミリ秒後に呼び出されるとは限らない点に 注目することは重要です - Node.js はコールバックが呼び出される正確なタイミングも、 呼び出される順番も保証しません。 コールバックはできるだけ指定された時間に近いタイミングで呼び出されます。

clearTimeout(timeoutId)#

タイムアウトがトリガーされるのを止めます。

setInterval(callback, delay, [arg], [...])#

delay ミリ秒が経過するごとに繰り返し callback が実行されるようにスケジュールします。 clearInterval() で使うことができる intervalId を返します。 オプションとして、コールバックへの引数を渡すこともできます。

clearInterval(intervalId)#

インターバルがトリガーされるのを止めます。

unref()#

setTimeout() あるいは setInterval() が返す不透明な値は、 アクティブであるにもかかわらず、それがイベントループの最後の一つになっても プログラムの実行を継続しないタイマを作ることを可能にする、 timer.unref() メソッドを持っています。 既に unref されたタイマで再び unref が呼び出されても影響はありません。

setTimeout()unref された場合、イベントループを起こすために独立した タイマが作成されるため、それらがあまりに多く作成されるとイベントループの パフォーマンスに悪影響を与えます -- 賢明に使ってください。

ref()#

以前に unref されたタイマは、明示的に ref() を呼び出すことで プログラムを実行したままにするよう要求することができます。 既に ref されたタイマで再び ref が呼び出されても影響はありません。

setImmediate(callback, [arg], [...])#

callback を「即時」 (I/O イベントのコールバックより後、setTimeout および setInterval よりも前) に実行するようスケジュールします。 clearImmediate() に渡すことのできる immediatedId を返します。 オプションとして、コールバックへの引数を渡すことができます。

即時実行のコールバックは、それが作られた順でキューイングされます。 コールバックのキューは全体が各イベントループの繰り返し毎に処理されます。 もし即時実行のコールバックが実行されている中から setImmediate() を呼び出しても、そのコールバックは次のイベントループの繰り返しまで 呼び出されません。

clearImmediate(immediateId)#

setImmediate() に渡した関数が呼び出されることを中止します。

Modules#

Stability: 5 - Locked

Node はシンプルなモジュールローディングシステムを持ちます。 Node では、ファイルとモジュールは1対1に対応します。 例として、 foo.js は、同じディレクトリにある circle.js をロードしています。

foo.js の内容:

var circle = require('./circle.js');
console.log( 'The area of a circle of radius 4 is '
           + circle.area(4));

circle.js の内容:

var PI = Math.PI;

exports.area = function (r) {
  return PI * r * r;
};

exports.circumference = function (r) {
  return 2 * PI * r;
};

circle.js モジュールは area()circumference() を公開しています。 関数やオブジェクトをモジュールのルートに加えるには、 exports という特別なオブジェクトに加えます。

モジュールのローカル変数は関数に包まれているかのようにプライベートになります。 この例の場合、変数 PIcircle.js のプライベート変数です。

モジュールのルートとして関数 (たとえばコンストラクタ) を後悔したり、 プロパティを一つずつ代入するのではなく、完全なオブジェクトを一度に 公開したければ、exports の代わりに module.exportsに代入します。

以下では、bar.jssquare モジュールが公開するコンストラクタを 使用しています。

var square = require('./square.js');
var mySquare = square(2);
console.log('The area of my square is ' + mySquare.area());

square.js モジュールは square.js で定義されています。

// assigning to exports will not modify module, must use module.exports
module.exports = function(width) {
  return {
    area: function() {
      return width * width;
    }
  };
}

モジュールシステムは require("module") モジュールによって実装されます。

Cycles#

require() が循環的に呼び出される場合、実行が完了していないモジュールが 返されることがあります。

次の状況を考えてください:

a.js:

console.log('a starting');
exports.done = false;
var b = require('./b.js');
console.log('in a, b.done = %j', b.done);
exports.done = true;
console.log('a done');

b.js:

console.log('b starting');
exports.done = false;
var a = require('./a.js');
console.log('in b, a.done = %j', a.done);
exports.done = true;
console.log('b done');

main.js:

console.log('main starting');
var a = require('./a.js');
var b = require('./b.js');
console.log('in main, a.done=%j, b.done=%j', a.done, b.done);

main.jsa.js をロードすると、a.jsb.js をロードします。 ポイントは、b.jsa.js のロードを試みることです。 無限ループを避けるため、a.js がエクスポートしたオブジェクトの 未完了のコピーb.js モジュールに返されます。 b.js のロードが完了すると、exports オブジェクトが a.js モジュールに 提供されます。

main.js が両方のモジュールをロードするまでには、どちらも完了します。 このプログラムの出力はこのようになります:

$ node main.js
main starting
a starting
b starting
in b, a.done = false
b done
in a, b.done = true
a done
in main, a.done=true, b.done=true

プログラムが循環参照するモジュールを持つ場合は、計画が適切か確認してください。

Core Modules#

Node にはバイナリにコンパイル済みのいくつかのモジュールがあります。 これらのモジュールについては、このドキュメントの他の場所でより詳しく記述されています。

コアモジュールは、 Node のソースの lib/ フォルダにて定義されています。

require() では常にコアモジュールの識別名を優先的に解釈します。 例えば require('http') は、例え同名のファイルが存在していたとしても、常にビルトイインの HTTP モジュールを返します。

File Modules#

指定された名前のファイルが見つからなければ、 Node は指定されたファイル名に .js.json、または .node を付けたものを読み込もうとします。

.js ファイルは JavaScript ファイルとして解釈され、 .json ファイルは JSON ファイルとして解釈されます。 一方 .node ファイルはコンパイル済みのアドオンモジュールとして解釈され、 dlopen を使って読み込まれます。

'/' から始まるモジュールは、ファイルへの絶対パスと見なされます。 例えば、 require('/home/marco/foo.js')/home/macro/foo.js を読み込みます。

'./' から始まるモジュールは、 require() を呼んだファイルからの相対パスになります。 すなわち、 foo.js から require('./circle') によって circle.js を読み込むには、 circle.jsfoo.js と同じディレクトリに存在していなければなりません。

'/' や './' が先頭になければ、モジュールは "コアモジュール" であるかもしくは node_modules フォルダから読み込まれることになります。

与えられたパスが存在しなかった場合、require()code プロパティに 'MODULE_NOT_FOUND' を設定したエラーをスローします。

Loading from node_modules Folders#

もし require() に渡されたモジュール識別子がネイティブモジュールではなく、かつ '/''../''./' から始まらないならば、 Node は現在のモジュールの親ディレクトリに '/node_modules' を付与してそこからモジュールを読み込もうとします。

そこに見つからない場合はさらに親ディレクトリに移動し、モジュールが見つかるか root ディレクトリに到達するまで同様のことを繰り返していきます。

例えば '/home/ry/projects/foo.js' の中で require('bar.js') を呼んでいた場合、 Node は下記の位置を上から順番に見ていきます。

  • /home/ry/projects/node_modules/bar.js
  • /home/ry/node_modules/bar.js
  • /home/node_modules/bar.js
  • /node_modules/bar.js

この仕組みによって、プログラムはクラッシュを避けるために依存関係を上書きすることができるのです。

Folders as Modules#

プログラムとライブラリをディレクトリ内にまとめて、そのエントリポイントを提示するという便利な方法もあります。 それには require() に引数として何を渡すかによって3通りの方法があります。

1つ目は、 package.json というファイルをフォルダ直下に作成し、 main モジュールを指定するという方法です。 例えば、 package.json は以下のようなファイルになります:

{ "name" : "some-library",
  "main" : "./lib/some-library.js" }

もし ./some-library フォルダ内にこのファイルがあれば、 require('./some-library')./some-library/lib/some-library.js を読みにいきます。

これは、 Node が package.json の存在に気づくことによってもたらされます。

もし package.json がディレクトリに存在していなければ、 Node はそのディレクトリで index.js もしくは index.node を探します。 例えば、もし上の例で package.json がいるが存在しないとすると、 require('./some-library') は以下のファイルを読み込もうとします:

  • ./some-library/index.js
  • ./some-library/index.node

Caching#

モジュールは初めて読み込まれたときにキャッシュされます。 すなわち(他のキャッシュと同様に) require('foo') を呼ぶたびに、もし引数の意味するものが同一のファイルであったなら全く同一のオブジェクトが返されます。

require('foo') が複数回呼び出されても、モジュールが複数回実行されることにはなりません。 これは重要な特徴です。 そのため、「部分的に完了した」オブジェクトを返すことで、 推移的な依存関係が循環していてもロードすることができます。

もしモジュールを複数回実行したければ、関数を公開して、 その関数を呼び出してください。

Module Caching Caveats#

モジュールは解決されたファイル名に基づいてキャッシュされます。 異なる場所にあるモジュールから呼び出されたモジュールは、 (node_module フォルダからロードされるため) 異なったファイル名で 解決されることがあるため、 require('foo') が常に同じオブジェクトを返す 保証はなく、異なるファイルとして解決されます。

The module Object#

!-- name=module -->

  • {Object}

どのモジュールでも、module 自由変数は現在のモジュールを表現するオブジェクトを 参照します。 利便性のため、module.exportsexports オブジェクトを通じて 参照することもできます。 module は実際はグローバルではなく、各モジュールのローカル変数です。

module.exports#

  • Object

module.exports オブジェクトはモジュールシステムによって作成されます。 時々これは受け入れらません; 多くの人々は、モジュールが何らかのクラスのインスタンスであることを望みます。 それには、公開したいオブジェクトを module.exports に割り当てます。 望ましいオブジェクトを exports へ代入することは、ローカル変数 exports への 再代入に過ぎずないことに注意すべきです。 それはおそらく、やりたかったことではないでしょう。

例えば a.js と呼ばれるモジュールを作るとしたら

var EventEmitter = require('events').EventEmitter;

module.exports = new EventEmitter();

// Do some work, and after some time emit
// the 'ready' event from the module itself.
setTimeout(function() {
  module.exports.emit('ready');
}, 1000);

そして別のファイルで

var a = require('./a');
a.on('ready', function() {
  console.log('module a is ready');
});

module.exports への代入はすぐに行わなければなりません。 コールバックの中ではできません。以下は動きません。

x.js:

setTimeout(function() {
  module.exports = { a: "hello" };
}, 0);

y.js:

var x = require('./x');
console.log(x.a);

exports alias#

モジュール内で利用出来る exports 変数は、最初は module.exports への参照です。 他の変数と同様、それに新しい値を割り当てると元の値はもはや束縛されません。

その振る舞いを示すために、この仮定の実装を想像してください。

function require(...) {
  // ...
  function (module, exports) {
    // Your module code here
    exports = some_func;        // re-assigns exports, exports is no longer
                                // a shortcut, and nothing is exported.
    module.exports = some_func; // makes your module export 0
  } (module, module.exports);
  return module;
}

ガイドラインとして、もし exportsmodule.exports の間の関係が魔法のように 見えるなら、exports を無視して module.exports だけを使うようにしてください。

module.require(id)#

  • id {String}
  • Return: {Object} 解決されたモジュールの module.exports

module.require メソッドは、元のモジュールが require() を呼び出したかのようにモジュールをロードするために提供されています。

それには module オブジェクトの参照が必要なことに注意してください。 require()module.exports を返した後、一般的に module はそのモジュールのコードで のみ 利用可能です。 それが使われるようにするには、明示的にエクスポートする必要があります。

module.id#

  • String

モジュールの識別子。通常は完全に解決されたファイル名です。

module.filename#

  • String

完全に解決されたモジュールのファイル名です。

module.loaded#

  • Boolean

モジュールのロードが完了したか,あるいはローディング中かを示します。

module.parent#

  • Module Object

このモジュールを要求したモジュールです。

module.children#

  • Array

このモジュールが要求したモジュールです。

All Together...#

require() が呼び出されると、正確なファイル名を得るために require.resolve() が使われます。

上で述べたことをまとめると、 require.resolve は以下の擬似コードで記述されるようなハイレベルなアルゴリズムに則っています:

require(X) from module at path Y
1. If X is a core module,
   a. return the core module
   b. STOP
2. If X begins with './' or '/' or '../'
   a. LOAD_AS_FILE(Y + X)
   b. LOAD_AS_DIRECTORY(Y + X)
3. LOAD_NODE_MODULES(X, dirname(Y))
4. THROW "not found"

LOAD_AS_FILE(X)
1. If X is a file, load X as JavaScript text.  STOP
2. If X.js is a file, load X.js as JavaScript text.  STOP
3. If X.node is a file, load X.node as binary addon.  STOP

LOAD_AS_DIRECTORY(X)
1. If X/package.json is a file,
   a. Parse X/package.json, and look for "main" field.
   b. let M = X + (json main field)
   c. LOAD_AS_FILE(M)
2. If X/index.js is a file, load X/index.js as JavaScript text.  STOP
3. If X/index.node is a file, load X/index.node as binary addon.  STOP

LOAD_NODE_MODULES(X, START)
1. let DIRS=NODE_MODULES_PATHS(START)
2. for each DIR in DIRS:
   a. LOAD_AS_FILE(DIR/X)
   b. LOAD_AS_DIRECTORY(DIR/X)

NODE_MODULES_PATHS(START)
1. let PARTS = path split(START)
2. let ROOT = index of first instance of "node_modules" in PARTS, or 0
3. let I = count of PARTS - 1
4. let DIRS = []
5. while I > ROOT,
   a. if PARTS[I] = "node_modules" CONTINUE
   c. DIR = path join(PARTS[0 .. I] + "node_modules")
   b. DIRS = DIRS + DIR
   c. let I = I - 1
6. return DIRS

Loading from the global folders#

NODE_PATH 環境変数に絶対パスをコロンで区切ったリストを設定すると、 node は他で見つからなかったモジュールをそれらのパスから探します。 (注意: Windows では、NODE_PATH はコロンではなくセミコロンで区切られます)

加えると、node は以下の場所から検索します。

  • 1: $HOME/.node_modules
  • 2: $HOME/.node_libraries
  • 3: $PREFIX/lib/node

$HOME はユーザのホームディレクトリ、$PREFIX は node を configure した時の node_prefix です。

これらは主に歴史的な理由によるものです。 あなたが依存するものはローカルの node_modules フォルダに置くことが 強く推奨されます。それは素早くロードされ、確実です。

Accessing the main module#

ファイルがNodeによって直接実行される場合、その modulerequire.main に設定されます。 これは、ファイルが直接実行されたかを決定できることを意味します。

require.main === module

foo.js ファイルの場合、node foo.js と実行された場合にこれは true になりますが、require('./foo') で実行された場合は false になります。

modulefilename プロパティ (通常 __filename と同じです) を提供するため、現在のアプリケーションのエントリポイントは require.main.filename をチェックすることで得ることができます。

Addenda: Package Manager Tips#

Node の require() は普通のディレクトリ構造をサポートできるよう汎用的に設計されています。 dpkgrpmnpm のようなパッケージ管理プログラムは修正なしに Node モジュールからネイティブパッケージを組み立てることができるでしょう。

推奨するディレクトリ構造は次のようになります:

例えば /usr/lib/node/<some-package>/<some-version> フォルダに、あるパッケージの特定のバージョンを保持する形式です。

パッケージは相互に依存しあうことがあります。 foo パッケージをインストールするためにはある特定のバージョンの bar パッケージをインストールする必要があります。 bar パッケージ自身も依存関係をもっているので、ときには依存関係が衝突したり循環したりすることがあります。

Node はモジュールの realpath (シンボリックリンクを解釈します)を調べ、その依存関係を上述の node_modules フォルダの仕組みで探しにいきます。 これによって次のような構造をとてもシンプルに解釈することができます。

  • /usr/lib/node/foo/1.2.3/ - foo パッケージの中身。バージョン1.2.3。
  • /usr/lib/node/bar/4.3.2/ - bar パッケージの中身。 foo が依存している。
  • /usr/lib/node/foo/1.2.3/node_modules/bar - /usr/lib/node/bar/4.3.2/ へのシンボリックリンク。
  • /usr/lib/node/bar/4.3.2/node_modules/* - bar が依存しているパッケージへのシンボリックリンク。

このようにして、もし仮に依存関係に循環や衝突が見つかったとしても、全てのモジュールは依存しているパッケージの特定のバージョンを取得することができます。

foo パッケージの中で require('bar') したら、 /usr/lib/node/foo/1.2.3/node_modules/bar からリンクされているバージョンを取得します。 そして、 bar パッケージ内で require('quux') を呼んだら、 /usr/lib/node/bar/4.3.2/node_modules/quux からリンクされているバージョンを取得します。

さらに、モジュールを探索する過程をより最適化するために、 /usr/lib/node にパッケージを置くよりも /usr/lib/node_modules/<name>/<version> に置くのをお勧めします。 そうすることで Node は見つからない依存パッケージを /usr/node_modules/node_modules に探しにいかなくてもようなります。

Node の REPL でモジュールを使えるようにするために、 /usr/lib/node_modules フォルダを $NODE_PATH 環境変数に追加するとよいでしょう。 node_modules フォルダを使ったモジュール探索は全て相対的なものであり、 require() を呼び出したファイルの絶対パスを基準としているので、パッケージ自体はどこにでも配置することができます。

Addons#

アドオンは動的に共有オブジェクトをリンクします。 それらは、C や C++ のライブラリに接合点を提供します。 API はいくつかのライブラリの知識が必要で、(現時点では) かなり複雑です。

  • V8 JavaScript は C++ のライブラリです。 JavaScript のオブジェクト作成や関数呼び出し等のインタフェースに使用されます。 ドキュメントは主に、v8.h のヘッダファイル (Node のソースツリーの中の deps/v8/include/v8.h) に記されていますが、 オンライン で参照することもできます。
  • libuv は C のイベントループライブラリです。 ファイル記述子が読み取り可能になるのを待つとき、タイマーを待つとき、 シグナルを受信するのを待つときはいつでも、 libv のインタフェースが必要になります。 つまり、何らかの I/O 処理をすると必ず libuv を使う必要があるということです。
  • Node の内部ライブラリ。 もっとも重要なのは node::ObjectWrap クラスで、 このクラスから派生させることが多くなるでしょう。
  • その他。どのような物が利用できるかは deps/ 以下を参照してさい。

Node は全ての依存ライブラリを実行ファイルに静的にコンパイルします。 モジュールのコンパイル時には、それらのリンクについて一切気にする必要は有りません。

以下のサンプルの全ては ダウンロード から利用することができ、独自のアドオンの出発点になるでしょう。

Hello world#

では、 以下の JavaScript コードと同じ様に動作する小さなアドオンを C++ で作成してみましょう。

module.exports.hello = function() { return 'world'; };

最初に hello.cc というファイルを作成します:

// hello.cc
#include <node.h>

using namespace v8;

void Method(const FunctionCallbackInfo<Value>& args) {
  Isolate* isolate = Isolate::GetCurrent();
  HandleScope scope(isolate);
  args.GetReturnValue().Set(String::NewFromUtf8(isolate, "world"));
}

void init(Handle<Object> exports) {
  NODE_SET_METHOD(exports, "hello", Method);
}

NODE_MODULE(addon, init)

全ての Node アドオンは初期化関数をエクスポートしなければならないことに 注意してください。

void Initialize (Handle<Object> exports);
NODE_MODULE(module_name, Initialize)

NODE_MODULE は関数ではないので、その後にセミコロンを付けてはいけません (node.h を参照してください)。

module_name は最終的なバイナリのファイル名 (拡張子 .node を除く) とマッチする必要があります。

このソースコードは、addon.node というバイナリアドオンとしてビルドされる必要が有ります。 そのために binding.gyp と呼ばれる、あなたのモジュールをビルドするための 構成を JSON 的なフォーマットで記述したファイルを作成します。 このファイルは node-gyp によってコンパイルされます。

{
  "targets": [
    {
      "target_name": "addon",
      "sources": [ "hello.cc" ]
    }
  ]
}

次のステップは現在のプラットフォームに適したプロジェクトビルドファイルを 生成することです。 node-gyp configure を使います。

これで、Makefile (Unix プラットフォームの場合)、または vcxproj ファイル (Windows の場合) が build/ ディレクトリに作られます。 次に node-gyp build コマンドを起動します。

これでコンパイルされた .node バインディングファイルが作成されます! コンパイルされたバインディングファイルは build/Release/ にあります。

ビルドされた hello.node モジュールを require で指定することにより、 このバイナリアドオンを Node プロジェクトの hello.js から利用することが 可能になります。

// hello.js
var addon = require('./build/Release/addon');

console.log(addon.hello()); // 'world'

さらに詳しい情報については下記のパターンか、

https://github.com/arturadib/node-qt を実際のプロダクトにおける 例として参照してください。

Addon patterns#

以下は初心者に役立つアドオンのパターンです。 v8 の様々な API についてはオンラインの v8 reference が、 そして ハンドルやスコープ、関数テンプレートなどいくつかの概念については v8 の Embedder's Guide が 役に立つでしょう。

このサンプルを利用できるようにするには、node-gyp を使用して コンパイルする必要があります。 以下の binding.gyp ファイルを作成します。

{
  "targets": [
    {
      "target_name": "addon",
      "sources": [ "addon.cc" ]
    }
  ]
}

一つ以上の .cc ファイルがある場合は、単純に sources 配列にファイル名を 加えるだけです。例:

"sources": ["addon.cc", "myexample.cc"]

これで binding.gyp の準備ができました。 アドオンをコンフィギュアおよびビルドするには:

$ node-gyp configure build

Function arguments#

以下のパターンは JavaScript から呼び出された関数で引数を読み出したり、 結果を返す方法を示します。これは addon.cc でのみ必要となります。

// addon.cc
#include <node.h>

using namespace v8;

void Add(const FunctionCallbackInfo<Value>& args) {
  Isolate* isolate = Isolate::GetCurrent();
  HandleScope scope(isolate);

  if (args.Length() < 2) {
    isolate->ThrowException(Exception::TypeError(
        String::NewFromUtf8(isolate, "Wrong number of arguments")));
    return;
  }

  if (!args[0]->IsNumber() || !args[1]->IsNumber()) {
    isolate->ThrowException(Exception::TypeError(
        String::NewFromUtf8(isolate, "Wrong arguments")));
    return;
  }

  Local<Number> num = Number::New(args[0]->NumberValue() +
      args[1]->NumberValue());

  args.GetReturnValue().Set(num);
}

void Init(Handle<Object> exports) {
  NODE_SET_METHOD(exports, "add", Add);
}

NODE_MODULE(addon, Init)

以下の JavaScript コード片でテストすることができます。

// test.js
var addon = require('./build/Release/addon');

console.log( 'This should be eight:', addon.add(3,5) );

Callbacks#

JavaScript の関数を C++ の関数に渡してそこから呼び出すことができます。 これは addon.cc です:

// addon.cc
#include <node.h>

using namespace v8;

void RunCallback(const FunctionCallbackInfo<Value>& args) {
  Isolate* isolate = Isolate::GetCurrent();
  HandleScope scope(isolate);

  Local<Function> cb = Local<Function>::Cast(args[0]);
  const unsigned argc = 1;
  Local<Value> argv[argc] = { String::NewFromUtf8(isolate, "hello world") };
  cb->Call(Context::GetCurrent()->Global(), argc, argv);
}

void Init(Handle<Object> exports, Handle<Object> module) {
  NODE_SET_METHOD(module, "exports", RunCallback);
}

NODE_MODULE(addon, Init)

この例は二つの引数を取る形式の Init() を使用して、第2引数で完全な module オブジェクトを受け取っていることに注意してください。 これは、exports のプロパティとして関数を加える代わりに、アドオンが 一つの関数で exports を完全に上書きすることを可能にします。

以下の JavaScript コード片でテストすることができます。

// test.js
var addon = require('./build/Release/addon');

addon(function(msg){
  console.log(msg); // 'hello world'
});

Object factory#

C++ 関数の中から新しいオブジェクトを作成して返すことができます。 以下の addon.cc のパターンでは、createObject() に渡された文字列を 反映する msg プロパティを持ったオブジェクトを返します。

// addon.cc
#include <node.h>

using namespace v8;

void CreateObject(const FunctionCallbackInfo<Value>& args) {
  Isolate* isolate = Isolate::GetCurrent();
  HandleScope scope(isolate);

  Local<Object> obj = Object::New();
  obj->Set(String::NewFromUtf8(isolate, "msg"), args[0]->ToString());

  args.GetReturnValue().Set(obj);
}

void Init(Handle<Object> exports, Handle<Object> module) {
  NODE_SET_METHOD(module, "exports", CreateObject);
}

NODE_MODULE(addon, Init)

テスト用の JavaScript:

// test.js
var addon = require('./build/Release/addon');

var obj1 = addon('hello');
var obj2 = addon('world');
console.log(obj1.msg+' '+obj2.msg); // 'hello world'

Function factory#

このパターンは C++ 関数をラップした JavaScript 関数を作成して返す方法を 示します。

// addon.cc
#include <node.h>

using namespace v8;

void MyFunction(const FunctionCallbackInfo<Value>& args) {
  Isolate* isolate = Isolate::GetCurrent();
  HandleScope scope(isolate);
  args.GetReturnValue().Set(String::NewFromUtf8(isolate, "hello world"));
}

void CreateFunction(const FunctionCallbackInfo<Value>& args) {
  Isolate* isolate = Isolate::GetCurrent();
  HandleScope scope(isolate);

  Local<FunctionTemplate> tpl = FunctionTemplate::New(MyFunction);
  Local<Function> fn = tpl->GetFunction();

  // omit this to make it anonymous
  fn->SetName(String::NewFromUtf8(isolate, "theFunction"));

  args.GetReturnValue().Set(fn);
}

void Init(Handle<Object> exports, Handle<Object> module) {
  NODE_SET_METHOD(module, "exports", CreateFunction);
}

NODE_MODULE(addon, Init)

テスト:

// test.js
var addon = require('./build/Release/addon');

var fn = addon();
console.log(fn()); // 'hello world'

Wrapping C++ objects#

ここでは、 C++ オブジェクト/クラスをラップし、JavaScript から new 演算子を使って インスタンス化できる MyObject を作成します。 最初にメインモジュール addon.cc を準備します:

// addon.cc
#include <node.h>
#include "myobject.h"

using namespace v8;

void InitAll(Handle<Object> exports) {
  MyObject::Init(exports);
}

NODE_MODULE(addon, InitAll)

次に、node::ObjectWrap を継承したラッパーを myobject.h に作成します。

// myobject.h
#ifndef MYOBJECT_H
#define MYOBJECT_H

#include <node.h>
#include <node_object_wrap.h>

class MyObject : public node::ObjectWrap {
 public:
  static void Init(v8::Handle<v8::Object> exports);

 private:
  explicit MyObject(double value = 0);
  ~MyObject();

  static void New(const v8::FunctionCallbackInfo<v8::Value>& args);
  static void PlusOne(const v8::FunctionCallbackInfo<v8::Value>& args);
  static v8::Persistent<v8::Function> constructor;
  double value_;
};

#endif

公開したい様々なメソッドを myobject.cc に実装します。 ここでは、コンストラクタに渡された値に加算する plusOne を公開しています:

// myobject.cc
#include "myobject.h"

using namespace v8;

Persistent<Function> MyObject::constructor;

MyObject::MyObject(double value) : value_(value) {
}

MyObject::~MyObject() {
}

void MyObject::Init(Handle<Object> exports) {
  Isolate* isolate = Isolate::GetCurrent();

  // Prepare constructor template
  Local<FunctionTemplate> tpl = FunctionTemplate::New(New);
  tpl->SetClassName(String::NewFromUtf8(isolate, "MyObject"));
  tpl->InstanceTemplate()->SetInternalFieldCount(1);

  // Prototype
  NODE_SET_PROTOTYPE_METHOD(tpl, "plusOne", PlusOne);

  constructor.Reset(isolate, tpl->GetFunction());
  exports->Set(String::NewFromUtf8(isolate, "MyObject"),
               tpl->GetFunction());
}

void MyObject::New(const FunctionCallbackInfo<Value>& args) {
  Isolate* isolate = Isolate::GetCurrent();
  HandleScope scope(isolate);

  if (args.IsConstructCall()) {
    // Invoked as constructor: `new MyObject(...)`
    double value = args[0]->IsUndefined() ? 0 : args[0]->NumberValue();
    MyObject* obj = new MyObject(value);
    obj->Wrap(args.This());
    args.GetReturnValue().Set(args.This());
  } else {
    // Invoked as plain function `MyObject(...)`, turn into construct call.
    const int argc = 1;
    Local<Value> argv[argc] = { args[0] };
    Local<Function> cons = Local<Function>::New(isolate, constructor);
    args.GetReturnValue().Set(cons->NewInstance(argc, argv));
  }
}

void MyObject::PlusOne(const FunctionCallbackInfo<Value>& args) {
  Isolate* isolate = Isolate::GetCurrent();
  HandleScope scope(isolate);

  MyObject* obj = ObjectWrap::Unwrap<MyObject>(args.This());
  obj->value_ += 1;

  args.GetReturnValue().Set(Number::New(obj->value_));
}

これでテストします:

// test.js
var addon = require('./build/Release/addon');

var obj = new addon.MyObject(10);
console.log( obj.plusOne() ); // 11
console.log( obj.plusOne() ); // 12
console.log( obj.plusOne() ); // 13

Factory of wrapped objects#

JavaScript の new 演算子で明示的にインスタンス化することなく、 ネイティブオブジェクトを作成できるようにしたい場合に便利です。例:

var obj = addon.createObject();
// instead of:
// var obj = new addon.Object();

createObjectaddon.cc` に登録しましょう:

// addon.cc
#include <node.h>
#include "myobject.h"

using namespace v8;

void CreateObject(const FunctionCallbackInfo<Value>& args) {
  Isolate* isolate = Isolate::GetCurrent();
  HandleScope scope(isolate);
  MyObject::NewInstance(args);
}

void InitAll(Handle<Object> exports, Handle<Object> module) {
  MyObject::Init();

  NODE_SET_METHOD(module, "exports", CreateObject);
}

NODE_MODULE(addon, InitAll)

myobject.h にオブジェクトを生成する static メソッド NewInstance を 導入しましょう (すなわち,それが JavaScript 内の new の働きをします)。

// myobject.h
#ifndef MYOBJECT_H
#define MYOBJECT_H

#include <node.h>
#include <node_object_wrap.h>

class MyObject : public node::ObjectWrap {
 public:
  static void Init();
  static void NewInstance(const v8::FunctionCallbackInfo<v8::Value>& args);

 private:
  explicit MyObject(double value = 0);
  ~MyObject();

  static void New(const v8::FunctionCallbackInfo<v8::Value>& args);
  static void PlusOne(const v8::FunctionCallbackInfo<v8::Value>& args);
  static v8::Persistent<v8::Function> constructor;
  double value_;
};

#endif

実装は前述の myobject.cc と同様です:

// myobject.cc
#include <node.h>
#include "myobject.h"

using namespace v8;

Persistent<Function> MyObject::constructor;

MyObject::MyObject(double value) : value_(value) {
}

MyObject::~MyObject() {
}

void MyObject::Init() {
  Isolate* isolate = Isolate::GetCurrent();
  // Prepare constructor template
  Local<FunctionTemplate> tpl = FunctionTemplate::New(New);
  tpl->SetClassName(String::NewFromUtf8(isolate, "MyObject"));
  tpl->InstanceTemplate()->SetInternalFieldCount(1);

  // Prototype
  NODE_SET_PROTOTYPE_METHOD(tpl, "plusOne", PlusOne);

  constructor.Reset(isolate, tpl->GetFunction());
}

void MyObject::New(const FunctionCallbackInfo<Value>& args) {
  Isolate* isolate = Isolate::GetCurrent();
  HandleScope scope(isolate);

  if (args.IsConstructCall()) {
    // Invoked as constructor: `new MyObject(...)`
    double value = args[0]->IsUndefined() ? 0 : args[0]->NumberValue();
    MyObject* obj = new MyObject(value);
    obj->Wrap(args.This());
    args.GetReturnValue().Set(args.This());
  } else {
    // Invoked as plain function `MyObject(...)`, turn into construct call.
    const int argc = 1;
    Local<Value> argv[argc] = { args[0] };
    Local<Function> cons = Local<Function>::New(isolate, constructor);
    args.GetReturnValue().Set(cons->NewInstance(argc, argv));
  }
}

void MyObject::NewInstance(const FunctionCallbackInfo<Value>& args) {
  Isolate* isolate = Isolate::GetCurrent();
  HandleScope scope(isolate);

  const unsigned argc = 1;
  Handle<Value> argv[argc] = { args[0] };
  Local<Function> cons = Local<Function>::New(isolate, constructor);
  Local<Object> instance = cons->NewInstance(argc, argv);

  args.GetReturnValue().Set(instance);
}

void MyObject::PlusOne(const FunctionCallbackInfo<Value>& args) {
  Isolate* isolate = Isolate::GetCurrent();
  HandleScope scope(isolate);

  MyObject* obj = ObjectWrap::Unwrap<MyObject>(args.This());
  obj->value_ += 1;

  args.GetReturnValue().Set(Number::New(obj->value_));
}

これでテストします:

// test.js
var createObject = require('./build/Release/addon');

var obj = createObject(10);
console.log( obj.plusOne() ); // 11
console.log( obj.plusOne() ); // 12
console.log( obj.plusOne() ); // 13

var obj2 = createObject(20);
console.log( obj2.plusOne() ); // 21
console.log( obj2.plusOne() ); // 22
console.log( obj2.plusOne() ); // 23

Passing wrapped objects around#

C++ オブジェクトをラップして返すことに加えて、Node が提供するヘルパ関数 node::ObjectWrap::Unwrap を使用してアンラップすることもできます。 以下の addon.cc では、二つの MyObject オブジェクトを受け取る add() 関数を導入します:

// addon.cc
#include <node.h>
#include <node_object_wrap.h>
#include "myobject.h"

using namespace v8;

void CreateObject(const FunctionCallbackInfo<Value>& args) {
  Isolate* isolate = Isolate::GetCurrent();
  HandleScope scope(isolate);
  MyObject::NewInstance(args);
}

void Add(const FunctionCallbackInfo<Value>& args) {
  Isolate* isolate = Isolate::GetCurrent();
  HandleScope scope(isolate);

  MyObject* obj1 = node::ObjectWrap::Unwrap<MyObject>(
      args[0]->ToObject());
  MyObject* obj2 = node::ObjectWrap::Unwrap<MyObject>(
      args[1]->ToObject());

  double sum = obj1->value() + obj2->value();
  args.GetReturnValue().Set(Number::New(sum));
}

void InitAll(Handle<Object> exports) {
  MyObject::Init();

  NODE_SET_METHOD(exports, "createObject", CreateObject);
  NODE_SET_METHOD(exports, "add", Add);
}

NODE_MODULE(addon, InitAll)

よりおもしろくするために、myobject.h にパブリックメソッドを導入しましょう。 したがって、アンラップされたオブジェクトのプライベート変数を調べることが できます。

// myobject.h
#ifndef MYOBJECT_H
#define MYOBJECT_H

#include <node.h>
#include <node_object_wrap.h>

class MyObject : public node::ObjectWrap {
 public:
  static void Init();
  static void NewInstance(const v8::FunctionCallbackInfo<v8::Value>& args);
  inline double value() const { return value_; }

 private:
  explicit MyObject(double value = 0);
  ~MyObject();

  static void New(const v8::FunctionCallbackInfo<v8::Value>& args);
  static v8::Persistent<v8::Function> constructor;
  double value_;
};

#endif

myobject.cc の実装はこれまでと同様です:

// myobject.cc
#include <node.h>
#include "myobject.h"

using namespace v8;

Persistent<Function> MyObject::constructor;

MyObject::MyObject(double value) : value_(value) {
}

MyObject::~MyObject() {
}

void MyObject::Init() {
  Isolate* isolate = Isolate::GetCurrent();

  // Prepare constructor template
  Local<FunctionTemplate> tpl = FunctionTemplate::New(New);
  tpl->SetClassName(String::NewFromUtf8(isolate, "MyObject"));
  tpl->InstanceTemplate()->SetInternalFieldCount(1);

  constructor.Reset(isolate, tpl->GetFunction());
}

void MyObject::New(const FunctionCallbackInfo<Value>& args) {
  Isolate* isolate = Isolate::GetCurrent();
  HandleScope scope(isolate);

  if (args.IsConstructCall()) {
    // Invoked as constructor: `new MyObject(...)`
    double value = args[0]->IsUndefined() ? 0 : args[0]->NumberValue();
    MyObject* obj = new MyObject(value);
    obj->Wrap(args.This());
    args.GetReturnValue().Set(args.This());
  } else {
    // Invoked as plain function `MyObject(...)`, turn into construct call.
    const int argc = 1;
    Local<Value> argv[argc] = { args[0] };
    Local<Function> cons = Local<Function>::New(isolate, constructor);
    args.GetReturnValue().Set(cons->NewInstance(argc, argv));
  }
}

void MyObject::NewInstance(const FunctionCallbackInfo<Value>& args) {
  Isolate* isolate = Isolate::GetCurrent();
  HandleScope scope(isolate);

  const unsigned argc = 1;
  Handle<Value> argv[argc] = { args[0] };
  Local<Function> cons = Local<Function>::New(isolate, constructor);
  Local<Object> instance = cons->NewInstance(argc, argv);

  args.GetReturnValue().Set(instance);
}

これでテストします:

// test.js
var addon = require('./build/Release/addon');

var obj1 = addon.createObject(10);
var obj2 = addon.createObject(20);
var result = addon.add(obj1, obj2);

console.log(result); // 30

process#

process はグローバルオブジェクトで、どこからでもアクセスすることができます。 それは EventEmitter のインスタンスです。

Exit Codes#

未完了の非同期な操作が無くなると、Node はステータスコード 0 で正常に 終了します。その他のケースでは、以下のステータスコードが使われます。

  • 1 捕捉されなかった致命的な例外 - 捕捉されなかった例外があり、 それがドメインや uncaughtException イベントハンドラによって 処理されなかった。
  • 2 - 未使用 (Bashに組み込まれた誤用のために予約)。
  • 3 内部的な JavaScript のパースエラー - Node がプロセスを ブートストラップする内部用の JavaScript ソースコードでパースエラーが 発生した。 これはきわめてまれで、通常 Node 自身を開発している時にしか起こりません。
  • 4 内部的な JavaScript の評価失敗 - Node がプロセスを ブートストラップする内部用の JavaScript ソースコードが評価された際、 関数を返すことに失敗した。 これはきわめてまれで、通常 Node 自身を開発している時にしか起こりません。
  • 5 致命的なエラー - 致命的で回復不可能なエラーが V8 で発生した。 通常、標準エラー出力に接頭辞 FATAL ERROR とともにメッセージが出力されます。
  • 6 内部的エラーハンドラが関数ではない - 捕捉されない例外が発生したが、 内部的な例外ハンドラにどういうわけか関数ではないものが設定されていて 呼び出せなかった。
  • 7 内部的なエラーハンドラが実行時に失敗 - 捕捉されない例外が発生し、 それを処理していた内部的な例外ハンドラ自身も例外をスローした。 これはたとえば、process.on('uncaughtException') または domain.on('error') のハンドラが例外をスローした場合に発生します。
  • 8 - 未使用。以前のバージョンの Node では、終了コード 8 は捕捉されない例外を 示すことがありました。
  • 9 不正な引数 - 未知のオプションが指定された、あるいは値が必須の オプションが値無しで指定された。
  • 10 内部的な JavaScript の実行時失敗 - Node がプロセスを ブートストラップする内部用の JavaScript ソースコードが評価された際、 例外をスローした。 これはきわめてまれで、通常 Node 自身を開発している時にしか起こりません。
  • 12 不正なデバッグ引数 - --debug または --debug-brk が指定されたが、 不正なポート番号が選ばれた。
  • >128 シグナルによる終了 - Node が SIGKILLSIGHUP などの致命的なシグナルを受け取ると、終了コードは 128 にシグナルコードを 加えた値になります。 これは終了コードが 7bit 整数で定義された時からの Unix の標準的な慣習で、 シグナルによる終了は最上位のビットを設定し、シグナルコードの値を含みます。

Event: 'exit'#

プロセスが終了しようとしている時に生成されます。 この位置からイベントループを抜けることを防ぐ方法はなく、全ての 'exit' リスナーの実行が完了すると、プロセスは終了します。 従って、このハンドラでできることは 同期 操作 だけ です。 これは (ユニットテストのように) モジュールの状態をチェックするのに適した フックとなります。 コールバックはプロセスの終了コードを唯一の引数として呼び出されます。

exit を監視する例:

process.on('exit', function(code) {
  // do *NOT* do this
  setTimeout(function() {
    console.log('This will not run');
  }, 0);
  console.log('About to exit with code:', code);
});

Event: 'uncaughtException'#

発生した例外がイベントループまでたどり着いた場合に生成されます。 もしこの例外に対するリスナーが加えられていれば、 デフォルトの動作 (それはスタックトレースをプリントして終了します) は起こりません。

uncaughtException を監視する例:

process.on('uncaughtException', function(err) {
  console.log('Caught exception: ' + err);
});

setTimeout(function() {
  console.log('This will still run.');
}, 500);

// Intentionally cause an exception, but don't catch it.
nonexistentFunc();
console.log('This will not run.');

uncaughtException は例外を扱うとても荒削りなメカニズムであることに 注意してください。

これを使う代わりに、ドメイン を使ってください。 それを使えば、捕まえられない例外が発生した後でもアプリケーションを 再開することができます!

これを Node.js における On Error Resume Next として 使わないで ください。 捕まえられなかった例外は、アプリケーション - および Node.js 自身の拡張 - が未定義の状態となることを意味します。 やみくもな再開は どんなことでも 起こることを意味します。

電源を引き抜きながらアプリケーションをアップグレードすることを 想像してください。 10 回中 9 回は何も起こりません - しかし 10 回目にはそのシステムは使えなくなるかもしれません。

これは警告です。

Signal Events#

プロセスがシグナルを受信した場合に生成されます。 SIGINT、SIGHUP、その他の POSIX 標準シグナル名の一覧について は sigaction(2) を参照してください。

SIGINTを監視する例:

// Start reading from stdin so we don't exit.
process.stdin.resume();

process.on('SIGINT', function() {
  console.log('Got SIGINT.  Press Control-D to exit.');
});

多くの端末プログラムで簡単に SIGINT を送る方法は Control-C を押すことです。

注意:

  • SIGUSR1 は Node.js がデバッガを起動するために予約されています。 リスナを登録することは出来ますが、デバッガの起動を止めることは出来ません。
  • SIGTERM および SIGINT は、Windows 以外のプラットフォームでは 128 + シグナル番号で終了する前にターミナルのモードをリセットする デフォルトのハンドラを持ちます。 これらのシグナルのどちらかにリスナが登録されると、デフォルトの振る舞いは 削除されます (node は終了しなくなります)。
  • SIGPIPE はデフォルトでは無視され、リスナを登録することが出来ます。
  • SIGHUP は Windows ではコンソールウィンドウが閉じられると発生します。 他のプラットフォームでも同様の条件で発生します。詳細は signal(7) を参照してください。 リスナを登録することは出来ますが、Windows では約 10 秒後に node は無条件に Windows によって終了されます。 Windows 以外のプラットフォームでは、SIGHUP のデフォルトの振る舞いは nodeを終了することですが、リスナを登録するとデフォルトの振る舞いは 削除されます。
  • SIGTERM は Windows ではサポートされません。 しかし、リスナを登録することは可能です。
  • 端末からの SIGINT は全てのプラットフォームでサポートされ、通常 CTRL+C (おそらく設定可能でしょう) によって生成されます。 ターミナルが raw モードの場合は生成されません。
  • SIGBREAK は Windows において CTRL+BREAK が推された時に送られます。 Windows 以外のプラットフォームでもリスナを登録することは出来ますが、 それを生成したり送信する方法はありません。
  • SIGWINCH はコンソールのサイズが変更された場合に送られます。 Windows では、カーソルが移動するか、tty が raw モードの場合に、 コンソールへ書き込むと発生します。
  • SIGKILL のリスナを組み込むことは出来ません。 それは全てのプラットフォームで node を無条件に終了します。
  • SIGSTOP のリスナを組み込むことは出来ません。

Windows はシグナルの送信をサポートしていませんが、nodeはprocess.kill()child_process.kill() をエミュレートする方法を提供します:

  • シグナル 0 は既存のプロセスを検索するためのものです。
  • SIGINTSIGTERM、そして SIGKILL は、ターゲットのプロセスが無条件に 終了する原因となります。

process.stdout#

stdout に対する Writable Stream です。

例: console.log の定義

console.log = function(d) {
  process.stdout.write(d + '\n');
};

process.stderrprocess.stdout は他のストリームと異なり、 書き込みは通常ブロックします。 それらが通常ファイルや TTY のファイル記述子を参照しているケースでは、 それらはブロックします。 パイプを参照しているケースでは、他のストリームと同様にブロックしません。

Node が TTY のコンテキストで実行されているかチェックするには、 process.stderr, process.stdout, または process.stdinisTTY プロパティを参照します。

$ node -p "Boolean(process.stdin.isTTY)"
true
$ echo "foo" | node -p "Boolean(process.stdin.isTTY)"
false

$ node -p "Boolean(process.stdout.isTTY)"
true
$ node -p "Boolean(process.stdout.isTTY)" | cat
false

より詳細は the tty docs を参照してください。

process.stderr#

stderr に対する Writable Stream です。

process.stderrprocess.stdout は他のストリームと異なり、 書き込みは通常ブロックします。 それらが通常ファイルや TTY のファイル記述子を参照しているケースでは、 それらはブロックします。 パイプを参照しているケースでは、他のストリームと同様にブロックしません。

process.stdin#

標準入力に対する Readable Stream です。 デフォルトでは、標準入力に対するストリームは中断されているため、 読み込みのためには process.stdin.resume() を呼び出さなければなりません。

標準入力をオープンして二つのイベントを監視する例:

process.stdin.resume();
process.stdin.setEncoding('utf8');

process.stdin.on('data', function(chunk) {
  process.stdout.write('data: ' + chunk);
});

process.stdin.on('end', function() {
  process.stdout.write('end');
});

process.argv#

コマンドライン引数を含む配列です。 最初の要素は 'node'、2 番目の要素は JavaScript ファイルの名前になります。 その後の要素はコマンドラインの追加の引数になります。

// print process.argv
process.argv.forEach(function(val, index, array) {
  console.log(index + ': ' + val);
});

このように出力されます:

$ node process-2.js one two=three four
0: node
1: /Users/mjr/work/node/process-2.js
2: one
3: two=three
4: four

process.execPath#

プロセスによって開始された実行可能ファイルの絶対パスです。

例:

/usr/local/bin/node

process.execArgv#

これはプロセス起動時に実行可能ファイルに与えられた node 固有の コマンドライン・オプション群です。 それらのオプションは process.argv には現れず、node の実行可能ファイルや スクリプト名、スクリプト名に続くどんなオプションも含まれません。 これらのオプションは親プロセスと同じ実行環境を持つ子プロセスを起動するために 役に立ちます。

例:

$ node --harmony script.js --version

process.execArgv の結果:

['--harmony']

そして process.argv の結果:

['/usr/local/bin/node', 'script.js', '--version']

process.abort()#

これは node をアボートさせます。 これは node が終了してコアファイルを生成する原因となります。

process.chdir(directory)#

プロセスのカレントワーキングディレクトリを変更します。 もし失敗した場合は例外をスローします。

console.log('Starting directory: ' + process.cwd());
try {
  process.chdir('/tmp');
  console.log('New directory: ' + process.cwd());
}
catch (err) {
  console.log('chdir: ' + err);
}

process.cwd()#

プロセスのカレントワーキングディレクトリを返します。

console.log('Current directory: ' + process.cwd());

process.env#

ユーザの環境を含むオブジェクトです。environ(7) を参照してください。

process.exit([code])#

指定の code でプロセスを終了します。 もし省略されると、「成功」を示すコード 0 を使って終了します。

「失敗」を示すコードで終了する例:

process.exit(1);

node を実行したシェルで終了コードが 1 であることを見ることができるでしょう。

process.exitCode#

プロセスが正常終了する場合や、process.exit() でコードが指定されなかった 場合に、終了コードとなる数値。

process.exit(code) でコードが指定されると、以前 process.exitCode に 設定された値は上書きされます。

process.getgid()#

注意: この関数は POSIX プラットフォーム (すなわち、Windows と Android 以外) でのみ利用可能です。

プロセスのグループ識別子を取得します (getgid(2) 参照)。 これは数値によるグループ ID で、グループ名ではありません。

if (process.getgid) {
  console.log('Current gid: ' + process.getgid());
}

process.setgid(id)#

注意: この関数は POSIX プラットフォーム (すなわち、Windows と Android 以外) でのみ利用可能です。

プロセスのグループ識別子を設定します (setgid(2) 参照)。 これは数値による ID もグループ名の文字列のどちらも受け入れます。 もしグループ名が指定されると、数値による ID が解決できるまでこのメソッドはブロックします。

if (process.getgid && process.setgid) {
  console.log('Current gid: ' + process.getgid());
  try {
    process.setgid(501);
    console.log('New gid: ' + process.getgid());
  }
  catch (err) {
    console.log('Failed to set gid: ' + err);
  }
}

process.getuid()#

注意: この関数は POSIX プラットフォーム (すなわち、Windows と Android 以外) でのみ利用可能です。

プロセスのユーザ識別子を取得します (getuid(2) 参照)。 これは数値によるユーザ ID で、ユーザ名ではありません。

if (process.getuid) {
  console.log('Current uid: ' + process.getuid());
}

process.setuid(id)#

注意: この関数は POSIX プラットフォーム (すなわち、Windows と Android 以外) でのみ利用可能です。

プロセスのユーザ識別子を設定します (setuid(2) 参照)。 これは数値による ID もユーザ名の文字列のどちらも受け入れます。 もしユーザ名が指定されると、数値による ID が解決できるまでこのメソッドはブロックします。

if (process.getuid && process.setuid) {
  console.log('Current uid: ' + process.getuid());
  try {
    process.setuid(501);
    console.log('New uid: ' + process.getuid());
  }
  catch (err) {
    console.log('Failed to set uid: ' + err);
  }
}

process.getgroups()#

注意: この関数は POSIX プラットフォーム (すなわち、Windows と Android 以外) でのみ利用可能です。

補助グループ ID の配列を返します。 POSIX は実効グループ ID が含まれることを明示していませんが、 Node.js では常にそれが含まれることを保証します。

process.setgroups(groups)#

注意: この関数は POSIX プラットフォーム (すなわち、Windows と Android 以外) でのみ利用可能です。

補助グループ ID を設定します。 これは特権オペレーションであり、ルートであるか、または CAP_SETGID ケーパビリティを持つ必要があります。

リストはグループ ID、グループ名、または両方を含むことができます。

process.initgroups(user, extra_group)#

注意: この関数は POSIX プラットフォーム (すなわち、Windows と Android 以外) でのみ利用可能です。

/etc/group を読み込んでグループアクセスリストを初期化し、 user がメンバーである全てのグループを使用します。 これは特権オペレーションであり、ルートであるか、または CAP_SETGID ケーパビリティを持つ必要があります。

user はユーザ名またはユーザ ID、 extra_group はグループ名またはグループ ID です。

特権を落とす際は、いくつか注意すべき事があります。例:

console.log(process.getgroups());         // [ 0 ]
process.initgroups('bnoordhuis', 1000);   // switch user
console.log(process.getgroups());         // [ 27, 30, 46, 1000, 0 ]
process.setgid(1000);                     // drop root gid
console.log(process.getgroups());         // [ 27, 30, 46, 1000 ]

process.version#

NODE_VERSION を提示するコンパイル済みプロパティです。

console.log('Version: ' + process.version);

process.versions#

node と依存ライブラリのバージョン文字列を提示します。

console.log(process.versions);

は以下のように出力します。

{ http_parser: '1.0',
  node: '0.10.4',
  v8: '3.14.5.8',
  ares: '1.9.0-DEV',
  uv: '0.10.3',
  zlib: '1.2.3',
  modules: '11',
  openssl: '1.0.1e' }

process.config#

現在のnode実行ファイルをコンパイルした際に使われた configure のオプションを JavaScript で表現したオブジェクトを保持します。 これは ./configure スクリプトを実行した際に生成された "cofnig.gypi" ファイルと同じです。

実際の出力の例です:

{ target_defaults:
   { cflags: [],
     default_configuration: 'Release',
     defines: [],
     include_dirs: [],
     libraries: [] },
  variables:
   { host_arch: 'x64',
     node_install_npm: 'true',
     node_prefix: '',
     node_shared_cares: 'false',
     node_shared_http_parser: 'false',
     node_shared_libuv: 'false',
     node_shared_v8: 'false',
     node_shared_zlib: 'false',
     node_use_dtrace: 'false',
     node_use_openssl: 'true',
     node_shared_openssl: 'false',
     strict_aliasing: 'true',
     target_arch: 'x64',
     v8_use_snapshot: 'true' } }

process.kill(pid, [signal])#

プロセスにシグナルを送ります。 pid はプロセス ID で signal は送信されるシグナルを文字列で記述したものです。 シグナルの名前は 'SIGINT''SIGHUP' のような文字列です。 省略すると、シグナルは 'SIGTERM' となります。 詳細は Signal Events および kill(2) を参照してください。

対象が存在しない場合はエラーがスローされます。 特殊なケースとして、プロセスが存在することを確認するためにシグナル 0 を使うことが出来ます。

この関数の名前が process.kill であるとおり、これは kill システムコールのように単にシグナルを送信することに注意してください。 対象のプロセスを殺すためだけでなく、他のシグナルも送信できます。

自身にシグナルを送信する例:

process.on('SIGHUP', function() {
  console.log('Got SIGHUP signal.');
});

setTimeout(function() {
  console.log('Exiting.');
  process.exit(0);
}, 100);

process.kill(process.pid, 'SIGHUP');

注意: SIGUSR1 が Node.js によって受け取られると、それはデバッガを起動します。 Signal Events を参照してください。

process.pid#

このプロセスの PID です。

console.log('This process is pid ' + process.pid);

process.title#

'ps' でどのよう表示されるかを設定するための getter/setter です。

setter が使われる場合、その最大長はプラットフォーム依存で、おそらく短いです。

Linux と OS X では、それは argv のメモリを上書きするため、 バイナリ名にコマンドライン引数を加えたものに制限されます。

v0.8 はより長いプロセスタイトル文字列で環境を上書きしていましたが、 それはいくつかの (はっきりしない) ケースにおいて、 潜在的に危険で混乱していました。

process.arch#

実行しているプロセッサのアーキテクチャ: 'arm''ia32'、または 'x64'

console.log('This processor architecture is ' + process.arch);

process.platform#

どのプラットフォームで動いているかを示します: 'darwin''freebsd''linux''sunos'、または 'win32'

console.log('This platform is ' + process.platform);

process.memoryUsage()#

Node プロセスのメモリ使用状況をバイト単位で記述したオブジェクトを返します。

var util = require('util');

console.log(util.inspect(process.memoryUsage()));

このように生成されます:

{ rss: 4935680,
  heapTotal: 1826816,
  heapUsed: 650472 }

heapTotalheapUsed は V8 のメモリ使用状況を参照します。

process.nextTick(callback)#

  • callback Function

現在のイベントループが完了した後、コールバック関数を呼び出します。

これは setTimeout(fn, 0) の単純なエイリアスではなく、 はるかに効率的です。 これは他のどの I/O イベント (タイマを含みます) が発生するよりも前に 実行されます。

console.log('start');
process.nextTick(function() {
  console.log('nextTick callback');
});
console.log('scheduled');
// Output:
// start
// scheduled
// nextTick callback

これは API の開発において、オブジェクトが構築された後で どんな I/O イベントが発生するよりも前に、 イベントハンドラを割り当てるチャンスをユーザに与えたい場合に重要になります。

function MyThing(options) {
  this.setupOptions(options);

  process.nextTick(function() {
    this.startDoingStuff();
  }.bind(this));
}

var thing = new MyThing();
thing.getReadyForStuff();

// thing.startDoingStuff() gets called now, not before.

API は 100% 同期的か、100% 非同期的かのどちらかであることがとても重要です。 この例を考えてみてください:

// WARNING!  DO NOT USE!  BAD UNSAFE HAZARD!
function maybeSync(arg, cb) {
  if (arg) {
    cb();
    return;
  }

  fs.stat('file', cb);
}

この API は危険です。こうすると:

maybeSync(true, function() {
  foo();
});
bar();

foo()bar() のどちらが先に呼び出されるか不明瞭になります。

以下のアプローチはずっと優れています:

function definitelyAsync(arg, cb) {
  if (arg) {
    process.nextTick(cb);
    return;
  }

  fs.stat('file', cb);
}

注意: イベントループの各繰り返しでは、I/O が処理される に nextTick のキューが完全に空にされます。 この結果、再帰的に設定された nextTick のコールバックは、 while (true); ループのように全てのI/O をブロックします

process.umask([mask])#

プロセスのファイルモード作成マスクを設定または読み込みます。 子プロセスは親プロセスからマスクを継承します。 mask 引数が与えられると元のマスクが返され、そうでなければ現在のマスクが返されます。

var oldmask, newmask = 0644;

oldmask = process.umask(newmask);
console.log('Changed umask from: ' + oldmask.toString(8) +
            ' to ' + newmask.toString(8));

process.uptime()#

Node が実行されてからの秒数です。

process.hrtime()#

高分解能な現在時刻を [seconds, nanoseconds] の配列で返します。 過去の任意の時間との比較することができます。 それは一日における時刻には関連が無いため、クロックドリフトに影響されません。 主な用途はベンチマークやインターバルの測定です。

以前に process.hrtime() を呼び出した結果を渡すことにより、 差分を得ることができます。これはベンチマークやインターバルの測定に便利です。

var time = process.hrtime();
// [ 1800216, 25 ]

setTimeout(function() {
  var diff = process.hrtime(time);
  // [ 1, 552 ]

  console.log('benchmark took %d nanoseconds', diff[0] * 1e9 + diff[1]);
  // benchmark took 1000000527 nanoseconds
}, 1000);

Async Listeners#

Stability: 1 - Experimental

AsyncListener API は、開発者が非同期イベントの有効期間中に キーとなるイベントの通知を受け取ることを可能にする、 AsyncWrap クラスへの JavaScript インターフェースです。 Node は内部的に多くの非同期イベントを扱うため、この API を使用することは アプリケーションのパフォーマンスに 重大な影響 を与えます。

process.createAsyncListener(callbacksObj[, userData])#

  • callbacksObj {Object} 非同期イベントのライフサイクル中に、 指定された回数だけ呼び出されるオプションのコールバックを含むオブジェクト。
  • userData {Value} 全てのコールバックに渡される値。

構築された AsyncListener オブジェクトを返します。

非同期イベントを捉えるには、process.addAsyncListener()callbacksObj か既存の AsyncListener インスタンスのいずれかを渡してください。 同じ AsyncListener インスタンスは一度だけアクティブなキューに加えられます。 それ以降、インスタンスの追加を試みても無視されます。

イベントの捕捉を止めるには、AsyncListener インスタンスを process.removeAsyncListener() に渡してください。 それは以前に加えられた AsyncListener がコールバックされなくなることを 意味 しません。 一度非同期イベントに加えられると、それは非同期処理のコールスタックが有効な間、 持続します。

関数のパラメータの説明:

callbacksObj: オプションのフィールドを3つ持つことができる Object です。

  • create(userData): 非同期イベントが生成された時に呼び出される関数。 関数がもし Value を返すなら、それはイベントに割り当てられ、 process.createAsyncListener()storageValue 引数に渡された値を 上書きします。 作成時に storageValue の初期値が渡されていた場合、asyncListener() は 関数の引数としてそれを受け取ります。
  • before(context, userData): 非同期コールバックが実行される前に 呼び出される関数です。 それは呼び出される関数の context (すなわち this) と、 asyncListener の戻り値または構築時に渡された値 (両方の場合) のどちらかが storageValue として渡されます。
  • after(context, userData): 非同期イベントのコールバックが実行された後で 呼び出される関数です。 コールバックがエラーをスローしてそれが処理されなければ、 これは呼び出されないことに注意してください。
  • error(userData, error): イベントのコールバックがスローすると 呼び出されます。 もし登録された関数が true を返すと、Node はエラーが正しく処理されたと見なし、 正常に実行を再開します。 複数の error() が登録されている場合、エラーが処理されたと AsyncListener に 認められるには、一つ だけでもコールバックが true を返す必要がありますが、 全ての error() コールバックは常に実行されます。
  • userData: デフォルトで、新しいイベントのインスタンスに割り当てられる値 (つまり何でも)。create() が返す値によって上書きされるかもしれません。

userData が上書きされる例です:

process.createAsyncListener({
  create: function listener(value) {
    // value === true
    return false;
}, {
  before: function before(context, value) {
    // value === false
  }
}, true);

注意: EventEmitter は、非同期イベントを生成するために使われますが、 それ自身は非同期ではありません。 そのため、イベントが加えられても create() は呼び出されず、 コールバックが呼び出されても before/after は呼び出されません。

process.addAsyncListener(callbacksObj[, userData])#

process.addAsyncListener(asyncListener)#

AsyncListener オブジェクトを構築し、それを非同期イベントを捕捉するキューに 加えて返します。

関数の引数は process.createAsyncListener() と同じか、 構築された AsyncListener オブジェクトです。

エラーを捕捉する例:

var fs = require('fs');

var cntr = 0;
var key = process.addAsyncListener({
  create: function onCreate() {
    return { uid: cntr++ };
  },
  before: function onBefore(context, storage) {
    // Write directly to stdout or we'll enter a recursive loop
    fs.writeSync(1, 'uid: ' + storage.uid + ' is about to run\n');
  },
  after: function onAfter(context, storage) {
    fs.writeSync(1, 'uid: ' + storage.uid + ' is about to run\n');
  },
  error: function onError(storage, err) {
    // Handle known errors
    if (err.message === 'everything is fine') {
      fs.writeSync(1, 'handled error just threw:\n');
      fs.writeSync(1, err.stack + '\n');
      return true;
    }
  }
});

process.nextTick(function() {
  throw new Error('everything is fine');
});

// Output:
// uid: 0 is about to run
// handled error just threw:
// Error: really, it's ok
//     at /tmp/test2.js:27:9
//     at process._tickCallback (node.js:583:11)
//     at Function.Module.runMain (module.js:492:11)
//     at startup (node.js:123:16)
//     at node.js:1012:3

process.removeAsyncListener(asyncListener)#

AsyncListener を監視キューから削除します。

アクティブなキューから AsyncLister を削除することは、 登録されたイベントに対して asyncListener コールバックの 呼び出しが中断されることを意味 しません。 その後、コールバックが実行される間に生成される全てのイベントも、 将来の実行のために同じ asyncListener に割り当てられます。

var fs = require('fs');

var key = process.createAsyncListener({
  create: function asyncListener() {
    // Write directly to stdout or we'll enter a recursive loop
    fs.writeSync(1, 'You summoned me?\n');
  }
});

// We want to begin capturing async events some time in the future.
setTimeout(function() {
  process.addAsyncListener(key);

  // Perform a few additional async events.
  setTimeout(function() {
    setImmediate(function() {
      process.nextTick(function() { });
    });
  });

  // Removing the listener doesn't mean to stop capturing events that
  // have already been added.
  process.removeAsyncListener(key);
}, 100);

// Output:
// You summoned me?
// You summoned me?
// You summoned me?
// You summoned me?

4つの非同期イベントを記録したという事実は、Node の Timers 実装の詳細を 表しています。

非同期イベントの捕捉を特定のスタック上で止めたければ、 process.removeAsyncListener() はそのコールスタック自身で呼び出すべきです。 たとえば:

var fs = require('fs');

var key = process.createAsyncListener({
  create: function asyncListener() {
    // Write directly to stdout or we'll enter a recursive loop
    fs.writeSync(1, 'You summoned me?\n');
  }
});

// We want to begin capturing async events some time in the future.
setTimeout(function() {
  process.addAsyncListener(key);

  // Perform a few additional async events.
  setImmediate(function() {
    // Stop capturing from this call stack.
    process.removeAsyncListener(key);

    process.nextTick(function() { });
  });
}, 100);

// Output:
// You summoned me?

ユーザは削除したい AsyncListener をいつでも明示的に渡すべきです。 すべてのリスナを一度に削除することは出来ません。

util#

Stability: 4 - API Frozen

これらの関数はモジュール 'util' 内にあります。 require('util') を使うことでこれらにアクセスします。

util モジュールは、主に Node 自身の内部 API によるニーズを満たすために 設計されています。 これらのユーティリティの多くはあなたのプログラムでも役に立つでしょう。 しかしながら、もしこれらの機能にあなたの目的とするものが欠けているとしたら、 その時はあなた自身のユーティリティを作成する時です。 私たちは Node 内部の機能のために不必要などんな特性も util モジュールに加えることに関心がありません。

util.debuglog(section)#

  • section {String} デバッグするプログラムのセクション
  • Returns: {Function} ロギング関数

これは、NDOE_DEBUG 環境変数の有無に基づいて標準エラー出力に 条件付きで出力する関数を作成して返します。 もし section 名が環境変数に出現するなら、返される関数は console.error() と同じです。そうでなければ、何もしない関数が返されます。

例:

var debuglog = util.debuglog('foo');

var bar = 123;
debuglog('hello from foo [%d]', bar);

もしプログラムが環境 NODE_DEBUG=foo で実行されると、 これは次のように出力します。

FOO 3245: hello from foo [123]

3245 はプロセス ID です。 環境を設定することなく実行すると、これは出力されません。

NODE_DEBUG 環境変数はカンマ区切りで複数の値を設定することができます。 たとえば、NODE_DEBUG=fs,net,tls

util.format(format, [...])#

最初の引数を printf のようなフォーマットとして使用して、フォーマット化された 文字列を返します。

第一引数は文字列で、0 個以上の プレースホルダ を含みます。 それぞれのプレースホルダは対応する引数を変換した値で置換されます。 サポートするプレースホルダは:

  • %s - 文字列。
  • %d - 数値 (整数と浮動小数点数の両方)。
  • %j - JSON。もし引数が循環した参照を含む場合、それは'[Circular]' に置換されます。
  • %% - 一つのパーセント記号 ('%')。これは引数を消費しません。

プレースホルダに対応する引数が無い場合、そのプレースホルダは置換されません。

util.format('%s:%s', 'foo'); // 'foo:%s'

プレースホルダより多くの引数がある場合、余った引数は util.inspect() によって 文字列化され、それらはスペース区切りで連結されます。

util.format('%s:%s', 'foo', 'bar', 'baz'); // 'foo:bar baz'

第一引数がフォーマット文字列ではない場合、util.format() は全ての引数を スペース区切りで連結して返します。 ここの引数は util.inspect() で文字列に変換されます。

util.format(1, 2, 3); // '1 2 3'

util.log(string)#

タイムスタンプとともに stdout へ出力します。

require('util').log('Timestamped message.');

util.inspect(object, [options])#

デバッグで有用な、object の文字列表現を返します。

オプションの options オブジェクトは、フォーマット化された文字列の 特定の側面を変更するために渡すことができます。

  • showHidden - true の場合、 オブジェクトの Enumerable でないプロパティも表示されます。 デフォルトは false です。
  • depth - オブジェクトをフォーマットするために何回再帰するかを inspect に伝えます。 これは巨大で複雑なオブジェクトを調査する場合に便利です。 デフォルトは 2 です。 無限に再帰するには、null を渡します。
  • colors - true の場合、出力は ANSI カラーコードで色づけされます。 デフォルトは false です。 後述するように、色はカスタマイズ可能です。
  • customInspect - false の場合、オブジェクト独自の inspect(depth, opts) 関数は呼び出されません。デフォルトは false です。

util オブジェクトの全てのプロパティを調査する例:

var util = require('util');

console.log(util.inspect(util, { showHidden: true, depth: null }));

値はそれ自身のカスタム inspect(depth, opts) 関数を提供するかもしれません。 それは呼び出される時、現在の再帰的な深さおよび util.inspect() に渡された options オブジェクトを受け取ります。

Customizing util.inspect colors#

util.inspect が出力する色は、(有効であれば) util.inspect.styles および util.inspect.colors オブジェクトを通じてグローバルにカスタマイズすることが 可能です。

util.inspect.styles は各スタイルと util.inspect.colors に 定義された色を割り当てたマッピングです。 強調されるスタイルとそれらのデフォルト値は:

  • number (黄)
  • boolean (黄)
  • string (緑)
  • date (紫)
  • regexp (赤)
  • null (太字)
  • undefined (灰)
  • special - only function at this time (水色)
  • name (意図的にスタイル無し)

事前に定義された色は: whitegreyblackbluecyangreenmagentared、および yellow です。 bolditalicunderline、および inverse コードを使うこともできます。

オブジェクトは util.inspect() から呼び出される自前の inspect(depth) 関数を持つことができ、その結果はオブジェクトを調査するために使われます。

var util = require('util');

var obj = { name: 'nate' };
obj.inspect = function(depth) {
  return '{' + this.name + '}';
};

util.inspect(obj);
  // "{nate}"

全く別のオブジェクトを返すこともできます。 戻り値の文字列は、そのオブジェクトに従ってフォーマットされます。 これは JSON.stringify() の動作とよく似ています。

var obj = { foo: 'this will not show up in the inspect() output' };
obj.inspect = function(depth) {
  return { bar: 'baz' };
};

util.inspect(obj);
  // "{ bar: 'baz' }"

util.isArray(object)#

object が配列なら true を、それ以外は false を返します。

var util = require('util');

util.isArray([])
  // true
util.isArray(new Array)
  // true
util.isArray({})
  // false

util.isRegExp(object)#

objectRegExp なら true を、それ以外なら false を返します。

var util = require('util');

util.isRegExp(/some regexp/)
  // true
util.isRegExp(new RegExp('another regexp'))
  // true
util.isRegExp({})
  // false

util.isDate(object)#

objectDate なら true を、それ以外なら false を返します。

var util = require('util');

util.isDate(new Date())
  // true
util.isDate(Date())
  // false (without 'new' returns a String)
util.isDate({})
  // false

util.isError(object)#

objectError なら true を、それ以外なら false を返します。

var util = require('util');

util.isError(new Error())
  // true
util.isError(new TypeError())
  // true
util.isError({ name: 'Error', message: 'an error occurred' })
  // false

util.inherits(constructor, superConstructor)#

ある コンストラクタ からプロトタイプメソッドを継承します。 constructor のプロトタイプは superConstructor から作られたオブジェクトに設定されます。

さらなる利便性のために、superConstructorconstructor.super_ プロパティを通じてアクセスすることができるようになります。

var util = require("util");
var events = require("events");

function MyStream() {
    events.EventEmitter.call(this);
}

util.inherits(MyStream, events.EventEmitter);

MyStream.prototype.write = function(data) {
    this.emit("data", data);
}

var stream = new MyStream();

console.log(stream instanceof events.EventEmitter); // true
console.log(MyStream.super_ === events.EventEmitter); // true

stream.on("data", function(data) {
    console.log('Received data: "' + data + '"');
})
stream.write("It works!"); // Received data: "It works!"

util.debug(string)#

Stability: 0 - Deprecated: use console.error() instead.

console.error() に置き換えられて廃止予定です。

util.error([...])#

Stability: 0 - Deprecated: Use console.error() instead.

console.error() に置き換えられて廃止予定です。

util.puts([...])#

Stability: 0 - Deprecated: Use console.log() instead.

console.log() に置き換えられて廃止予定です。

util.print([...])#

Stability: 0 - Deprecated: Use console.log instead.

console.log() に置き換えられて廃止予定です。

util.pump(readableStream, writableStream, [callback])#

Stability: 0 - Deprecated: Use readableStream.pipe(writableStream)

stream.pipe() に置き換えられて廃止予定です。

Events#

Stability: 4 - API Frozen

Node のオブジェクトの多くはイベントを生成します: net.Serverは相手から接続するたびにイベントを生成し、 fs.readStreamはファイルがオープンされるたびにイベントを生成します。 イベントを生成する全てのオブジェクトは events.EventEmitter のインスタンスです。 次のようにすることでこのモジュールにアクセスできます: require("events");

通常、イベント名はキャメル記法による文字列で表現されますが、 厳格な制限ではなく、どんな文字列でも受け入れられます。

関数をオブジェクトにアタッチすることができ、それはイベントが生成された時に実行されます。 これらの関数はリスナと呼ばれます。 リスナ関数の中では、this はリスナがアタッチされている EventEmitter を参照します。

Class: events.EventEmitter#

EventEmitterクラスにアクセスするには、require('events').EventEmitter を使います。

EventEmitter のインスタンスがエラーに遭遇した時、 典型的な動作は 'error' イベントを生成することです。 node ではエラーイベントは特別に扱われます. もしそのリスナーがなければ、デフォルトの動作はスタックトレースを出力してプログラムを終了することです。

全ての EventEmitter は、新しいリスナーが加えられるとイベント 'newListener' を生成し、リスナーが削除されると 'removeListener' を生成します。

emitter.addListener(event, listener)#

emitter.on(event, listener)#

指定されたイベントに対するリスナー配列の最後にリスナーを追加します。

server.on('connection', function (stream) {
  console.log('someone connected!');
});

EventEmitter 自身を返すので、呼び出しをチェーンすることができます。

emitter.once(event, listener)#

一回限りのリスナーをイベントに追加します。 このリスナーは次にイベントが発生した時に限り起動され、その後で削除されます。

server.once('connection', function (stream) {
  console.log('Ah, we have our first user!');
});

EventEmitter 自身を返すので、呼び出しをチェーンすることができます。

emitter.removeListener(event, listener)#

指定されたイベントに対するリスナー配列からリスナーを削除します。 注意: リスナーの背後にあるリスナー配列のインデックスが変化します。

var callback = function(stream) {
  console.log('someone connected!');
};
server.on('connection', callback);
// ...
server.removeListener('connection', callback);

EventEmitter 自身を返すので、呼び出しをチェーンすることができます。

emitter.removeAllListeners([event])#

全てのリスナーまたは指定されたイベントに対するリスナーを削除します。

EventEmitter 自身を返すので、呼び出しをチェーンすることができます。

emitter.setMaxListeners(n)#

デフォルトでは、10 を越えるリスナが特定のイベントに追加されると、 EventEmitter は警告を出力します。 これはメモリリークを見つけるために役に立つデフォルト値です。 全ての EventEmitter が 10 に制限されなければならないわけではないことは 明らかです。この関数は制限を増やすことを許可します。 0 を設定すると無制限になります。

EventEmitter 自身を返すので、呼び出しをチェーンすることができます。

EventEmitter.defaultMaxListeners#

emitter.setMaxListeners(n) はインスタンス毎の上限を設定します。 このクラスプロパティは、現在と将来の 全ての EventEmitter インスタンスの上限を即座に設定します。 注意して使用してください。

emitter.setMaxListeners(n)EventEmitter.defaultMaxListeners よりも 優先されることに注意してください。

emitter.listeners(event)#

指定されたイベントに対するリスナー配列を返します。

server.on('connection', function (stream) {
  console.log('someone connected!');
});
console.log(util.inspect(server.listeners('connection'))); // [ [Function] ]

emitter.emit(event, [arg1], [arg2], [...])#

提供された引数の並びでそれぞれのリスナーを実行します。

イベントに対応するリスナがあった場合は true、それ以外は false を返します。

Class Method: EventEmitter.listenerCount(emitter, event)#

与えられたイベントのリスナー数を返します。

Event: 'newListener'#

  • event String The event name
  • listener Function The event handler function

このイベントは新しいリスナーが追加されるたびに生成されます。 emitter.listeners(event) が返すリストに listener が含まれるかどうかは未定義です。

Event: 'removeListener'#

  • event {String} イベント名
  • listener {Function} イベントハンドラ関数

このイベントはリスナが取り除かれるたびに生成されます。 emitter.listeners(event) が返すリストに listener が含まれるかどうかは未定義です。

Domain#

Stability: 2 - Unstable

ドメインは複数の異なる I/O 操作を一つのグループとして扱う方法を 提供します。 もし EventEmitter またはコールバックがドメインに登録されると、 'error' がイベントが発生したり例外がスローされた場合、 process.on('uncaughtException') ハンドラでエラーのコンテキストが失われたり、 プログラムがエラーコードと共に即座に終了する代わりに、 ドメインオブジェクトに通知されます

この機能は Node バージョン 0.8 からの新しいものです。 これはファーストパスであり、将来のバージョンで大きく変更されると予想されます。 是非これを使ってフィードバックをしてください。

これらは実験的であるため、ドメインの機能は domain モジュールが少なくとも 一回はロードされるまで無効になっています。 デフォルトではドメインは作成されず、デフォルトで登録もされません。 それは既存のプログラムに悪影響を与えることを防ぐために設計されています。 将来の Node.js バージョンではデフォルトで有効になることが期待されます。

Warning: Don't Ignore Errors!#

ドメインのエラーハンドラは、エラーが発生した時に プロセスを終了する代わりにはなりません。

JavaScript において「throw」がどのように働くかという性質により、 参照のリークや未定義の脆弱な状態を作ることなく「中断したところを取得する」 方法はほとんどありません。

スローされたエラーに対処するもっとも安全な方法はプロセスを終了することです。 もちろん、通常の Web サーバは多くの接続をオープンしていており、 他の誰かによって引き起こされたエラーのためにそれらをシャットダウンすることは 合理的ではありません。

よりよいアプローチは、エラーを引き起こしたリクエストにエラーを応答し、 それ以外の接続が正常に終了するまでの間、ワーカは新しいリクエストのリスニングを 止めることです。

この方法では、domain はクラスタモジュールと手を取り合う利用方法により、 ワーカプロセスがエラーに遭遇した場合に新しいワーカをフォークできます。 複数のマシンにスケールする node プログラムでは、 終端のプロキシやサービスレジストリは障害に注意し、 それに応じて対処することができます。

たとえば、これはいいアイディアではありません:

// XXX WARNING!  BAD IDEA!

var d = require('domain').create();
d.on('error', function(er) {
  // The error won't crash the process, but what it does is worse!
  // Though we've prevented abrupt process restarting, we are leaking
  // resources like crazy if this ever happens.
  // This is no better than process.on('uncaughtException')!
  console.log('error, but oh well', er.message);
});
d.run(function() {
  require('http').createServer(function(req, res) {
    handleRequest(req, res);
  }).listen(PORT);
});

domain の利用と、プログラムを複数のワーカプロセスに分割することによる 復元力により、とても安全にエラーを扱う、より適切な対処をすることができます。

// Much better!

var cluster = require('cluster');
var PORT = +process.env.PORT || 1337;

if (cluster.isMaster) {
  // In real life, you'd probably use more than just 2 workers,
  // and perhaps not put the master and worker in the same file.
  //
  // You can also of course get a bit fancier about logging, and
  // implement whatever custom logic you need to prevent DoS
  // attacks and other bad behavior.
  //
  // See the options in the cluster documentation.
  //
  // The important thing is that the master does very little,
  // increasing our resilience to unexpected errors.

  cluster.fork();
  cluster.fork();

  cluster.on('disconnect', function(worker) {
    console.error('disconnect!');
    cluster.fork();
  });

} else {
  // the worker
  //
  // This is where we put our bugs!

  var domain = require('domain');

  // See the cluster documentation for more details about using
  // worker processes to serve requests.  How it works, caveats, etc.

  var server = require('http').createServer(function(req, res) {
    var d = domain.create();
    d.on('error', function(er) {
      console.error('error', er.stack);

      // Note: we're in dangerous territory!
      // By definition, something unexpected occurred,
      // which we probably didn't want.
      // Anything can happen now!  Be very careful!

      try {
        // make sure we close down within 30 seconds
        var killtimer = setTimeout(function() {
          process.exit(1);
        }, 30000);
        // But don't keep the process open just for that!
        killtimer.unref();

        // stop taking new requests.
        server.close();

        // Let the master know we're dead.  This will trigger a
        // 'disconnect' in the cluster master, and then it will fork
        // a new worker.
        cluster.worker.disconnect();

        // try to send an error to the request that triggered the problem
        res.statusCode = 500;
        res.setHeader('content-type', 'text/plain');
        res.end('Oops, there was a problem!\n');
      } catch (er2) {
        // oh well, not much we can do at this point.
        console.error('Error sending 500!', er2.stack);
      }
    });

    // Because req and res were created before this domain existed,
    // we need to explicitly add them.
    // See the explanation of implicit vs explicit binding below.
    d.add(req);
    d.add(res);

    // Now run the handler function in the domain.
    d.run(function() {
      handleRequest(req, res);
    });
  });
  server.listen(PORT);
}

// This part isn't important.  Just an example routing thing.
// You'd put your fancy application logic here.
function handleRequest(req, res) {
  switch(req.url) {
    case '/error':
      // We do some async stuff, and then...
      setTimeout(function() {
        // Whoops!
        flerb.bark();
      });
      break;
    default:
      res.end('ok');
  }
}

Additions to Error objects#

どんな場合でも、ドメインに送られた Error オブジェクトは いくつかのフィールドが加えられます。

  • error.domain このエラーを最初に捕まえたドメイン。
  • error.domainEmitter このエラーオブジェクトと共に error イベントを 生成した EventEmitter。
  • error.domainBound ドメインに束縛されたコールバック関数で、 その第 1 引数にエラーが渡されたもの。
  • error.domainThrown エラーがスローされたか、EventEmitter から生成されたか、 それとも束縛されたコールバック関数に渡されたかを示す boolean 値。

Implicit Binding#

一度ドメインが作成されると、全ての 新しい EventEmitter オブジェクト (ストリームオブジェクトやリクエスト、レスポンス、その他を含む) は、 それが作成された時点でアクティブなドメインに暗黙的に束縛されます。

加えて、コールバックが低水準のイベントループ要求 (例えば fs.open()、 あるいは他のコールバックを受け取るメソッド) もアクティブなドメインに 束縛されます。 もしそれらが例外をスローすると、ドメインはそれを捕まえます。

必要以上にメモリを消費するのを防ぐため、ドメインオブジェクトそれ自身は 暗黙的にアクティブドメインの子として暗黙的には追加されません。 それをすれば、リクエストやレスポンスオブジェクトがきちんと GC されることを あまりにも簡単に妨害してしまうでしょう。

もしネストしたドメインを子として他のドメインに 加えたければ 明示的にそれを加えなければなりません。

暗黙的なドメインはスローされたエラーや 'error' イベントを、 ドメインの 'error' イベントにルーティングしますが、 その EventEmitter をドメインに登録しないので、domain.dispose() は EventEmitter をシャットダウンしません。 暗黙的なバインディングはスローされた例外と 'error' イベントにだけ 注意を払います。

Explicit Binding#

時には、使用中のドメインは特定の EventEmitter に使用されるべきではありません。 あるいは、EventEmitter はあるドメインのコンテキスト中で作成されますが、 その他のドメインに結びつけられるべきかもしれません。

例えば、HTTP サーバで使われるドメインが一つあるとしても、 おそらくリクエスト毎に独立したドメインを持ちたいでしょう。

これは明示的なバインディングによって可能となります。

例:

// create a top-level domain for the server
var serverDomain = domain.create();

serverDomain.run(function() {
  // server is created in the scope of serverDomain
  http.createServer(function(req, res) {
    // req and res are also created in the scope of serverDomain
    // however, we'd prefer to have a separate domain for each request.
    // create it first thing, and add req and res to it.
    var reqd = domain.create();
    reqd.add(req);
    reqd.add(res);
    reqd.on('error', function(er) {
      console.error('Error', er, req.url);
      try {
        res.writeHead(500);
        res.end('Error occurred, sorry.');
      } catch (er) {
        console.error('Error sending 500', er, req.url);
      }
    });
  }).listen(1337);
});

domain.create()#

  • return: Domain

新しいドメインオブジェクトを返します。

Class: Domain#

ドメインクラスはエラーのルーティングや捕まえられなかった例外をアクティブな ドメインにルーティングする機能をカプセル化します。

ドメインは EventEmitter の子クラスです。 これが捕まえたエラーを扱いたければ、'error' イベントを監視してください。

domain.run(fn)#

  • fn Function

与えられた関数をこのドメインのコンテキストで実行します。 このコンテキストで作成される全ての EventEmitter、タイマ、そして低水準の要求は 暗黙的にバインドされます。

これはドメインを使用するもっとも一般的な方法です。

例:

var d = domain.create();
d.on('error', function(er) {
  console.error('Caught error!', er);
});
d.run(function() {
  process.nextTick(function() {
    setTimeout(function() { // simulating some various async stuff
      fs.open('non-existent file', 'r', function(er, fd) {
        if (er) throw er;
        // proceed...
      });
    }, 100);
  });
});

この例では、プログラムはクラッシュせずに d.on('error') ハンドラが 呼び出されます。

domain.members#

  • Array

このドメインに明示的に加えられたタイマまたは EventEmitter の配列です。

domain.add(emitter)#

  • emitter {EventEmitter | Timer} ドメインに加えられる EventEmitter またはタイマ

明示的に EventEmitter をドメインに追加します。 この EventEmitter から呼ばれたどのイベントハンドラがエラーをスローしても、 あるいはこの EventEmitter が 'error' イベントを発生しても、 暗黙的にバインディングされたのと同様、それはこのドメインの 'error' イベントにルーティングされます。

これは同様に setIntervalu および setTimeout から返されるタイマでも 働きます。それらのコールバック関数がエラーをスローすると、それは ドメインの 'error' ハンドに捕まえられます。

もしタイマまたは EventEmitter が既に他のドメインに束縛されていた場合、 それは元のドメインから削除され、代わりにこのドメインに束縛されます。

domain.remove(emitter)#

  • emitter {EventEmitter | Timer} このドメインから削除される EventEmitter またはタイマ

これは domain.add(emitter) と対照的です。指定された EventEmitter を ドメインから削除します。

domain.bind(callback)#

  • callback {Function} コールバック関数
  • return: {Function} 束縛された関数

返される関数は与えられたコールバック関数のラッパーです。 返された関数が呼び出されると、スローされたエラーはドメインの 'error' イベントにルーティングされます。

Example#

var d = domain.create();

function readSomeFile(filename, cb) {
  fs.readFile(filename, 'utf8', d.bind(function(er, data) {
    // if this throws, it will also be passed to the domain
    return cb(er, data ? JSON.parse(data) : null);
  }));
}

d.on('error', function(er) {
  // an error occurred somewhere.
  // if we throw it now, it will crash the program
  // with the normal line number and stack message.
});

domain.intercept(callback)#

  • callback {Function} コールバック関数
  • return: {Function} インターセプトされた関数

このメソッドはほとんど domain.bind(callback) と同じです。 ただし、スローされたエラーを捕まえることに加えて、関数に渡される最初の引数が Error オブジェクトの場合もインターセプトします。

これは、一般的な if (er) return callback(er); パターンを一カ所で単一の エラーハンドラに置き換えることができます。

Example#

var d = domain.create();

function readSomeFile(filename, cb) {
  fs.readFile(filename, 'utf8', d.intercept(function(data) {
    // note, the first argument is never passed to the
    // callback since it is assumed to be the 'Error' argument
    // and thus intercepted by the domain.

    // if this throws, it will also be passed to the domain
    // so the error-handling logic can be moved to the 'error'
    // event on the domain instead of being repeated throughout
    // the program.
    return cb(null, JSON.parse(data));
  }));
}

d.on('error', function(er) {
  // an error occurred somewhere.
  // if we throw it now, it will crash the program
  // with the normal line number and stack message.
});

domain.enter()#

enter() メソッドは、run()bind()、そして intercept() メソッドを アクティブなドメインに結びつけるために使われます。 これは (このドメインオブジェクト、すなわち this を) domain.active および process.domain を設定し、ドメインモジュールによって管理される ドメインのスタックに暗黙的に積み上げます (ドメインのスタックに関する詳細は domain.exit() を参照)。

enter() の呼び出しはアクティブなドメインを変更することだけで、 ドメイン自身は変化しません。 enter()exit() は一つのドメインに対して何度でも呼び出すことができます。

もし enter() が呼び出されたドメインが破棄済みだと、 enter() は何も設定せずにリターンします。

domain.exit()#

exit() メソッドは現在のドメインから抜け出し、スタックから取り除きます。 非同期呼び出しのチェーンが異なるコンテキストに切り替わる場合はどんな時でも、 現在のドメインから確実に抜け出すことは重要です。 exit() の呼び出しは、ドメインに束縛された非同期呼び出しおよび I/O 操作のチェーンを、終端または途中で区切ります。

もし複数のネストしたドメインが現在の実行コンテキストに束縛されていると、 exit() はネストしたどのドメインからも抜け出します。

exit() の呼び出しはアクティブなドメインを変更することだけで、 ドメイン自身は変化しません。 enter()exit() は一つのドメインに対して何度でも呼び出すことができます。

もし exit() が呼び出されたドメインが破棄済みだと、 exit() は何も設定せずにリターンします。

domain.dispose()#

Stability: 0 - Deprecated.  IO 操作の明らかな失敗から回復するには、
ドメインに設定したエラーハンドラを通じておこなってください。

一度 dispose() が呼び出されると、run()bind()、または intercept() によってドメインに束縛されたコールバックはもうドメインが使われなくなります。 そして 'dispose' イベントが生成されます。

Buffer#

Stability: 3 - Stable

純粋な JavaScript は Unicode と相性がいいものの、バイナリデータの扱いはうまくありません。 TCP ストリームやファイルシステムを扱う場合は、オクテットストリームを処理する必要があります。 Node にはオクテットストリームを操作、作成、消費するためにいくつかの戦略があります。

生のデータは Buffer クラスのインスタンスに保存されます。 Buffer は整数の配列と似ていますが、 V8 ヒープの外部に割り当てられた生のメモリに対応します。 Buffer のサイズを変更することはできません。

Buffer クラスはグローバルなので、require('buffer') が必要になることは ほとんどありません。

バッファを JavaScript 文字列オブジェクトとの間で変換するにはエンコーディング方式を明示する必要があります。 いくつかのエンコーディング方式があります。

  • 'ascii' - 7bit の ASCII データ専用です。 このエンコーディング方式はとても高速で、もし上位ビットがセットされていれば取り除かれます。

  • 'utf8' - 可変長のバイト単位でエンコードされたUnicode文字。 多くのWebページやその他のドキュメントは UTF-8 を使っています。

  • 'utf16le' - 2 または 4 バイトのリトルエンディアンでエンコードされた Unicode 文字。 サロゲートペア (U+10000~U+10FFFF) もサポートされます。

  • 'ucs2' - 'utf16le' の別名です。

  • 'base64' - Base64 文字列エンコーディング.

  • 'binary' - 生のバイナリデータを各文字の最初の 8bit として使用するエンコーディング方式。 このエンコーディング方式はもはや価値がなく、Buffer オブジェクトでは可能な限り使用すべきではありません。 このエンコーディングは、Node の将来のバージョンで削除される予定です。

  • 'hex' - 各バイトを 2 桁の16進数文字列でエンコードします。

Class: Buffer#

Buffer クラスはバイナリデータを直接扱うためのグローバルな型です。 それは様々な方法で構築することができます。

new Buffer(size)#

  • size Number

size オクテットの新しいバッファを割り当てます。

new Buffer(array)#

  • array Array

オクテットの array を使用する新しいバッファを割り当てます。

new Buffer(str, [encoding])#

  • str String - エンコードされる文字列
  • encoding String - 使用するエンコード、Optional、Default: 'utf8'

与えられた str を内容とする新しいバッファを割り当てます。 encoding のデフォルトは 'utf8' です。

Class Method: Buffer.isEncoding(encoding)#

  • encoding {String} 検証するエンコーディング名

encoding が正しければ true、それ以外は false を返します。

Class Method: Buffer.isBuffer(obj)#

  • obj Object
  • Return: Boolean

objBuffer かどうかテストします。

Class Method: Buffer.byteLength(string, [encoding])#

  • string String
  • encoding String, 任意, デフォルト: 'utf8'
  • Return: Number

文字列の実際のバイト数を返します。encoding のデフォルトは 'utf8' です。 これは文字列の文字数を返す String.prototype.length と同じではありません。

例:

str = '\u00bd + \u00bc = \u00be';

console.log(str + ": " + str.length + " characters, " +
  Buffer.byteLength(str, 'utf8') + " bytes");

// ½ + ¼ = ¾: 9 characters, 12 bytes

Class Method: Buffer.concat(list, [totalLength])#

  • list {Array} 結合するバッファのリスト
  • totalLength {Number} 結合されるバッファ全体の長さ

リストに含まれるバッファ全体を結合した結果のバッファを返します。

リストが空の場合、または totalLength が 0 の場合は長さが 0 のバッファを返します。

リストが一つだけの要素を持つ場合、リストの先頭要素が返されます。

リストが複数の要素を持つ場合、新しいバッファが作成されます。

totalLength が与えられない場合はリスト中のバッファから求められます。 しかし、これは余計なループが必要になるため、明示的に長さを指定する方が 高速です。

buf.length#

  • Number

バイト数によるバッファのサイズ。 これは実際の内容のサイズではないことに注意してください。 length はバッファオブジェクトに割り当てられたメモリ全体を参照します。

buf = new Buffer(1234);

console.log(buf.length);
buf.write("some string", 0, "ascii");
console.log(buf.length);

// 1234
// 1234

buf.write(string, [offset], [length], [encoding])#

  • string String - バッファに書き込まれるデータ
  • offset Number, Optional, Default: 0
  • length Number, Optional
  • encoding String, Optional, Default: 'utf8'

与えられたエンコーディングを使用して、string をバッファの offset から書き込みます。 offset のデフォルトは 0encoding のデフォルトは 'utf8' です。 length は書き込むバイト数です。書き込まれたオクテット数を返します。 もし buffer が文字列全体を挿入するのに十分なスペースを含んでいなければ、文字列の一部だけを書き込みます。 length のデフォルトは buffer.length - offset です。 このメソッドは文字の一部だけを書き込むことはありません。

例: utf8 の文字列をバッファに書き込み、それをプリントします

buf = new Buffer(256);
len = buf.write('\u00bd + \u00bc = \u00be', 0);
console.log(len + " bytes: " + buf.toString('utf8', 0, len));

buf.toString([encoding], [start], [end])#

  • encoding String, Optional, Default: 'utf8'
  • start Number, Optional, Default: 0
  • end Number, Optional, Default: buffer.length

encoding (デフォルトは 'utf8') でエンコードされたバッファデータの start (デフォルトは 0) から end (デフォルトは buffer.length) までをデコードした文字列を返します。

上の buffer.write() の例を参照してください。

buf.toJSON()#

バッファインスタンスの JSON 表現を返します。 JSON.stringify() は Buffer のインスタンスを文字列化する際に、 この関数を暗黙的に呼び出します。

例:

var buf = new Buffer('test');
var json = JSON.stringify(buf);

console.log(json);
// '{"type":"Buffer","data":[116,101,115,116]}'

var copy = JSON.parse(json, function(key, value) {
    return value && value.type === 'Buffer'
      ? new Buffer(value.data)
      : value;
  });

console.log(copy);
// <Buffer 74 65 73 74>

buf[index]#

index の位置のオクテットを取得および設定します。 その値は個々のバイトを参照するので、妥当な範囲は 16 進の 0x00 から 0xFF または 0 から255までの間です。

例: ASCII 文字列を 1 バイトずつバッファにコピーします

str = "node.js";
buf = new Buffer(str.length);

for (var i = 0; i < str.length ; i++) {
  buf[i] = str.charCodeAt(i);
}

console.log(buf);

// node.js

buf.copy(targetBuffer, [targetStart], [sourceStart], [sourceEnd])#

  • targetBuffer Buffer object - コピー先の Buffer
  • targetStart Number, Optional, Default: 0
  • sourceStart Number, Optional, Default: 0
  • sourceEnd Number, Optional, Default: buffer.length

バッファ間でコピーします。 ソースとターゲットの領域は重なっていても構いません。 targetStartsourceStart のデフォルトは 0 です。 sourceEnd のデフォルトは buffer.length です。

undefined/NaN またはその他の不正な値が渡された場合は、 それぞれのデフォルトが設定されます。

例: バッファを2個作成し、buf1 の 16 バイト目から 19 バイト目を、 buf2 の 8 バイト目から始まる位置へコピーします。

buf1 = new Buffer(26);
buf2 = new Buffer(26);

for (var i = 0 ; i < 26 ; i++) {
  buf1[i] = i + 97; // 97 is ASCII a
  buf2[i] = 33; // ASCII !
}

buf1.copy(buf2, 8, 16, 20);
console.log(buf2.toString('ascii', 0, 25));

// !!!!!!!!qrst!!!!!!!!!!!!!

buf.slice([start], [end])#

  • start Number, Optional, Default: 0
  • end Number, Optional, Default: buffer.length

元のバッファと同じメモリを参照しますが、start (デフォルトは 0) と end (デフォルトは buffer.length) で示されるオフセットと長さを持つ 新しいバッファを返します。 負のインデックスはバッファの末尾から開始します。

新しいバッファスライスの変更は、オリジナルバッファのメモリを変更することになります!

例: ASCII のアルファベットでバッファを構築してスライスし、元のバッファで 1 バイトを変更します。

var buf1 = new Buffer(26);

for (var i = 0 ; i < 26 ; i++) {
  buf1[i] = i + 97; // 97 is ASCII a
}

var buf2 = buf1.slice(0, 3);
console.log(buf2.toString('ascii', 0, buf2.length));
buf1[0] = 33;
console.log(buf2.toString('ascii', 0, buf2.length));

// abc
// !bc

buf.readUInt8(offset, [noAssert])#

  • offset Number
  • noAssert Boolean, Optional, Default: false
  • Return: Number

バッファの指定された位置を符号無し 8bit 整数として読み込みます。

もし noAsserttrue なら offset の検証をスキップします。 これは offset がバッファの終端を越えてしまう場合があることを意味します。 デフォルトは false です。

例:

var buf = new Buffer(4);

buf[0] = 0x3;
buf[1] = 0x4;
buf[2] = 0x23;
buf[3] = 0x42;

for (ii = 0; ii < buf.length; ii++) {
  console.log(buf.readUInt8(ii));
}

// 0x3
// 0x4
// 0x23
// 0x42

buf.readUInt16LE(offset, [noAssert])#

buf.readUInt16BE(offset, [noAssert])#

  • offset Number
  • noAssert Boolean, Optional, Default: false
  • Return: Number

バッファの指定された位置を符号無し 16bit 整数として読み込みます。

もし noAsserttrue なら offset の検証をスキップします。 これは offset がバッファの終端を越えてしまう場合があることを意味します。 デフォルトは false です。

例:

var buf = new Buffer(4);

buf[0] = 0x3;
buf[1] = 0x4;
buf[2] = 0x23;
buf[3] = 0x42;

console.log(buf.readUInt16BE(0));
console.log(buf.readUInt16LE(0));
console.log(buf.readUInt16BE(1));
console.log(buf.readUInt16LE(1));
console.log(buf.readUInt16BE(2));
console.log(buf.readUInt16LE(2));

// 0x0304
// 0x0403
// 0x0423
// 0x2304
// 0x2342
// 0x4223

buf.readUInt32LE(offset, [noAssert])#

buf.readUInt32BE(offset, [noAssert])#

  • offset Number
  • noAssert Boolean, Optional, Default: false
  • Return: Number

バッファの指定された位置を符号無し 32bit 整数として読み込みます。

もし noAsserttrue なら offset の検証をスキップします。 これは offset がバッファの終端を越えてしまう場合があることを意味します。 デフォルトは false です。

例:

var buf = new Buffer(4);

buf[0] = 0x3;
buf[1] = 0x4;
buf[2] = 0x23;
buf[3] = 0x42;

console.log(buf.readUInt32BE(0));
console.log(buf.readUInt32LE(0));

// 0x03042342
// 0x42230403

buf.readInt8(offset, [noAssert])#

  • offset Number
  • noAssert Boolean, Optional, Default: false
  • Return: Number

バッファの指定された位置を符号付き 8bit 整数として読み込みます。

もし noAsserttrue なら offset の検証をスキップします。 これは offset がバッファの終端を越えてしまう場合があることを意味します。 デフォルトは false です。

バッファの内容を 2 の補数による符号付き値として扱うこと以外は buffer.readUInt8 と同じように動作します。

buf.readInt16LE(offset, [noAssert])#

buf.readInt16BE(offset, [noAssert])#

  • offset Number
  • noAssert Boolean, Optional, Default: false
  • Return: Number

バッファの指定された位置を符号付き 16bit 整数として読み込みます。

もし noAsserttrue なら offset の検証をスキップします。 これは offset がバッファの終端を越えてしまう場合があることを意味します。 デフォルトは false です。

バッファの内容を 2 の補数による符号付き値として扱うこと以外は buffer.readUInt16 と同じように動作します。

buf.readInt32LE(offset, [noAssert])#

buf.readInt32BE(offset, [noAssert])#

  • offset Number
  • noAssert Boolean, Optional, Default: false
  • Return: Number

バッファの指定された位置を符号付き 32bit 整数として読み込みます。

もし noAsserttrue なら offset の検証をスキップします。 これは offset がバッファの終端を越えてしまう場合があることを意味します。 デフォルトは false です。

バッファの内容を 2 の補数による符号付き値として扱うこと以外は buffer.readUInt32 と同じように動作します。

buf.readFloatLE(offset, [noAssert])#

buf.readFloatBE(offset, [noAssert])#

  • offset Number
  • noAssert Boolean, Optional, Default: false
  • Return: Number

バッファの指定された位置を 32bit 浮動小数点数として読み込みます。

もし noAsserttrue なら offset の検証をスキップします。 これは offset がバッファの終端を越えてしまう場合があることを意味します。 デフォルトは false です。

例:

var buf = new Buffer(4);

buf[0] = 0x00;
buf[1] = 0x00;
buf[2] = 0x80;
buf[3] = 0x3f;

console.log(buf.readFloatLE(0));

// 0x01

buf.readDoubleLE(offset, [noAssert])#

buf.readDoubleBE(offset, [noAssert])#

  • offset Number
  • noAssert Boolean, Optional, Default: false
  • Return: Number

バッファの指定された位置を 64bit 倍精度浮動小数点数として読み込みます。

もし noAsserttrue なら offset の検証をスキップします。 これは offset がバッファの終端を越えてしまう場合があることを意味します。 デフォルトは false です。

例:

var buf = new Buffer(8);

buf[0] = 0x55;
buf[1] = 0x55;
buf[2] = 0x55;
buf[3] = 0x55;
buf[4] = 0x55;
buf[5] = 0x55;
buf[6] = 0xd5;
buf[7] = 0x3f;

console.log(buf.readDoubleLE(0));

// 0.3333333333333333

buf.writeUInt8(value, offset, [noAssert])#

  • value Number
  • offset Number
  • noAssert Boolean, Optional, Default: false

value を符号無し 8bit 整数としてバッファの指定された位置に、 指定されたエンディアンで書き込みます。 value は妥当な 8bit 符号無し整数でなければならないことに注意してください。

もし noAsserttrue なら,valueoffset の検証をスキップします。 これは、value がこの関数で扱えるより大きな場合や、offset がバッファの終端を越えてしまう場合は、静かに捨てられることを意味します。 正確性に確信がない限り、これらを使用すべきではありません。 デフォルトは false です。

例:

var buf = new Buffer(4);
buf.writeUInt8(0x3, 0);
buf.writeUInt8(0x4, 1);
buf.writeUInt8(0x23, 2);
buf.writeUInt8(0x42, 3);

console.log(buf);

// <Buffer 03 04 23 42>

buf.writeUInt16LE(value, offset, [noAssert])#

buf.writeUInt16BE(value, offset, [noAssert])#

  • value Number
  • offset Number
  • noAssert Boolean, Optional, Default: false

value を符号無し 16bit 整数としてバッファの指定された位置に、 指定されたエンディアンで書き込みます。 value は妥当な 16bit 符号無し整数でなければならないことに注意してください。

もし noAsserttrue なら,valueoffset の検証をスキップします。 これは、value がこの関数で扱えるより大きな場合や、offset がバッファの終端を越えてしまう場合は、静かに捨てられることを意味します。 正確性に確信がない限り、これらを使用すべきではありません。 デフォルトは false です。

例:

var buf = new Buffer(4);
buf.writeUInt16BE(0xdead, 0);
buf.writeUInt16BE(0xbeef, 2);

console.log(buf);

buf.writeUInt16LE(0xdead, 0);
buf.writeUInt16LE(0xbeef, 2);

console.log(buf);

// <Buffer de ad be ef>
// <Buffer ad de ef be>

buf.writeUInt32LE(value, offset, [noAssert])#

buf.writeUInt32BE(value, offset, [noAssert])#

  • value Number
  • offset Number
  • noAssert Boolean, Optional, Default: false

value を符号無し 32bit 整数としてバッファの指定された位置に、 指定されたエンディアンで書き込みます。 value は妥当な 32bit 符号無し整数でなければならないことに注意してください。

もし noAsserttrue なら,valueoffset の検証をスキップします。 これは、value がこの関数で扱えるより大きな場合や、offset がバッファの終端を越えてしまう場合は、静かに捨てられることを意味します。 正確性に確信がない限り、これらを使用すべきではありません。 デフォルトは false です。

例:

var buf = new Buffer(4);
buf.writeUInt32BE(0xfeedface, 0);

console.log(buf);

buf.writeUInt32LE(0xfeedface, 0);

console.log(buf);

// <Buffer fe ed fa ce>
// <Buffer ce fa ed fe>

buf.writeInt8(value, offset, [noAssert])#

  • value Number
  • offset Number
  • noAssert Boolean, Optional, Default: false

value を符号付き 8bit 整数としてバッファの指定された位置に、 指定されたエンディアンで書き込みます。 value は妥当な 8bit 符号付き整数でなければならないことに注意してください。

もし noAsserttrue なら,valueoffset の検証をスキップします。 これは、value がこの関数で扱えるより大きな場合や、offset がバッファの終端を越えてしまう場合は、静かに捨てられることを意味します。 正確性に確信がない限り、これらを使用すべきではありません。 デフォルトは false です。

value を 2 の補数による符号付き値として書き込むこと以外は buffer.writeUInt8 と同じように動作します。

buf.writeInt16LE(value, offset, [noAssert])#

buf.writeInt16BE(value, offset, [noAssert])#

  • value Number
  • offset Number
  • noAssert Boolean, Optional, Default: false

value を符号付き 16bit 整数としてバッファの指定された位置に、 指定されたエンディアンで書き込みます。 value は妥当な 16bit 符号付き整数でなければならないことに注意してください。

もし noAsserttrue なら,valueoffset の検証をスキップします。 これは、value がこの関数で扱えるより大きな場合や、offset がバッファの終端を越えてしまう場合は、静かに捨てられることを意味します。 正確性に確信がない限り、これらを使用すべきではありません。 デフォルトは false です。

value を 2 の補数による符号付き値として書き込むこと以外は buffer.writeUInt16 と同じように動作します。

buf.writeInt32LE(value, offset, [noAssert])#

buf.writeInt32BE(value, offset, [noAssert])#

  • value Number
  • offset Number
  • noAssert Boolean, Optional, Default: false

value を符号付き 32bit 整数としてバッファの指定された位置に、 指定されたエンディアンで書き込みます。 value は妥当な 32bit 符号付き整数でなければならないことに注意してください。

もし noAsserttrue なら,valueoffset の検証をスキップします。 これは、value がこの関数で扱えるより大きな場合や、offset がバッファの終端を越えてしまう場合は、静かに捨てられることを意味します。 正確性に確信がない限り、これらを使用すべきではありません。 デフォルトは false です。

value を 2 の補数による符号付き値として書き込むこと以外は buffer.writeUInt32 と同じように動作します。

buf.writeFloatLE(value, offset, [noAssert])#

buf.writeFloatBE(value, offset, [noAssert])#

  • value Number
  • offset Number
  • noAssert Boolean, Optional, Default: false

value を 32bit 浮動小数点数としてバッファの指定された位置に、 指定されたエンディアンで書き込みます。 value が 32bit 浮動小数点数でない場合の振る舞いは未定義であることに 注意してください。

もし noAsserttrue なら,valueoffset の検証をスキップします。 これは、value がこの関数で扱えるより大きな場合や、offset がバッファの終端を越えてしまう場合は、静かに捨てられることを意味します。 正確性に確信がない限り、これらを使用すべきではありません。 デフォルトは false です。

例:

var buf = new Buffer(4);
buf.writeFloatBE(0xcafebabe, 0);

console.log(buf);

buf.writeFloatLE(0xcafebabe, 0);

console.log(buf);

// <Buffer 4f 4a fe bb>
// <Buffer bb fe 4a 4f>

buf.writeDoubleLE(value, offset, [noAssert])#

buf.writeDoubleBE(value, offset, [noAssert])#

  • value Number
  • offset Number
  • noAssert Boolean, Optional, Default: false

value を 64bit 倍精度浮動小数点数としてバッファの指定された位置に、 指定されたエンディアンで書き込みます。 value は妥当な 64bit 倍精度浮動小数点数でなければならないことに注意してください。

もし noAsserttrue なら,valueoffset の検証をスキップします。 これは、value がこの関数で扱えるより大きな場合や、offset がバッファの終端を越えてしまう場合は、静かに捨てられることを意味します。 正確性に確信がない限り、これらを使用すべきではありません。 デフォルトは false です。

例:

var buf = new Buffer(8);
buf.writeDoubleBE(0xdeadbeefcafebabe, 0);

console.log(buf);

buf.writeDoubleLE(0xdeadbeefcafebabe, 0);

console.log(buf);

// <Buffer 43 eb d5 b7 dd f9 5f d7>
// <Buffer d7 5f f9 dd b7 d5 eb 43>

buf.fill(value, [offset], [end])#

  • value
  • offset Number, Optional
  • end Number, Optional

指定された値でバッファを埋めます。 offset (デフォルトは 0) と end (デフォルトは buffer.length) Fが与えられなかった場合はバッファ全体を埋めます。

var b = new Buffer(50);
b.fill("h");

buf.toArrayBuffer()#

バッファインスタンスのメモリをコピーした新しい ArrayBuffer を作成します。

buffer.INSPECT_MAX_BYTES#

  • Number, Default: 50

buffer.inspect() が呼び出された場合に返すバイト数です。 これはユーザモジュールによって上書きすることができます。

これはグローバルの Buffer やそのインスタンスではなく、 requrie('buffer') によって返される buffer モジュールのプロパティであることに注意してください。

Class: SlowBuffer#

プールされていない Buffer オブジェクトを返します。

多くの独立したバッファを割り当てることによるガーベッジコレクションの オーバーヘッドを避けるため、デフォルトでは 4KB 以下のバッファは大きな 単一のバッファから切り出されて割り当てられます。 このアプローチは、v8 が多くの「永続的な」オブジェクトを追跡して クリーンアップする必要を無くすため、パフォーマンスとメモリ使用量の両方を 改善します。

プールから得た小さなメモリ片を不確定の時間保持する必要がある場合は、 SlowBuffer を使ってプールされていない Buffer のインスタンスを作成し、 関連したビットを全てコピーすることが適切な場合があります。

// need to keep around a few small chunks of memory
var store = [];

socket.on('readable', function() {
  var data = socket.read();
  // allocate for retained data
  var sb = new SlowBuffer(10);
  // copy the data into the new allocation
  data.copy(sb, 0, 0, 10);
  store.push(sb);
});

しかし、これはアプリケーションで不適切なメモリの保持が盛大に観測された 後で、 最後の手段として控えめに使用されるべきです。

Stream#

Stability: 2 - Unstable

ストリームは Node の様々なオブジェクトで実装される抽象的なインタフェースです。 例えば HTTP サーバへのリクエスト標準出力と同様にストリームです。 ストリームは読み込み可能、書き込み可能、またはその両方です。 全てのストリームは EventEmitter のインスタンスです。

Stream のベースクラスは require('stream') でロードすることができます。 Readable ストリーム、Writable ストリーム、Duplex ストリーム、 Transform ストリームのベースクラスが提供されます。

このドキュメントは 3 つのセクションに分かれています。 最初に、プログラムでストリームを利用するために知っておく必要がある API について説明します。 もし独自のストリーミング API を実装しないのであれば、 そこで終わりにすることができます。

2番目のセクションでは、独自のストリームを実装する場合に必要となる API について説明します。 この API はそれが簡単にできるように設計されています。

3番目のセクションは、理解することなく変更してはならない 内部的なメカニズムや関数群を含めて、ストリームがどのように動作するかについて より詳しく説明します。

API for Stream Consumers#

ストリームは、ReadableWritable、またはその両方 (Duplex) のいずれかになることができます。

全てのストリームは EventEmitter ですが、Readable、Writable、または Duplex のいずれであるかによって、独自のメソッドやプロパティを持ちます。

もしストリームが ReadableWritable の両方であるなら、 それは以下の全てのメソッドとイベントを実装します。 Duplex または Transform ストリームの実装は多少異なる場合がありますが、 この API によって詳細に説明されます。

プログラムの中でストリームからのデータを消費するために、 ストリームのインターフェースを実装する必要はありません。 もしプログラムの中でストリーミングインターフェースを実装 する なら、 以下の ストリーム実装者向けの API を参照してください。

ほとんど全ての Node プログラムは、どんなに単純であっても、 何らかの方法でストリームを利用します。 これはストリームを利用する Node プログラムの例です:

var http = require('http');

var server = http.createServer(function (req, res) {
  // req is an http.IncomingMessage, which is a Readable Stream
  // res is an http.ServerResponse, which is a Writable Stream

  var body = '';
  // we want to get the data as utf8 strings
  // If you don't set an encoding, then you'll get Buffer objects
  req.setEncoding('utf8');

  // Readable streams emit 'data' events once a listener is added
  req.on('data', function (chunk) {
    body += chunk;
  })

  // the end event tells you that you have entire body
  req.on('end', function () {
    try {
      var data = JSON.parse(body);
    } catch (er) {
      // uh oh!  bad json!
      res.statusCode = 400;
      return res.end('error: ' + er.message);
    }

    // write back something interesting to the user:
    res.write(typeof data);
    res.end();
  })
})

server.listen(1337);

// $ curl localhost:1337 -d '{}'
// object
// $ curl localhost:1337 -d '"foo"'
// string
// $ curl localhost:1337 -d 'not json'
// error: Unexpected token o

Class: stream.Readable#

Readable ストリームのインターフェースは、あなたが読み込むデータの抽象的な 発生源 です。言い換えると、データは Readable ストリームから 出て きます。

Readable ストリームは、あなたがデータを受け取る準備ができたと指示するまでは、 データの生成を開始しません。

Readable ストリームは二つの "モード": flowing モードpaused モード を持っています。 flowing モードに入ると、データは下層のシステムから読み込まれると、 可能な限り素早くあなたのプログラムに届けられます。 paused モードでは、データの断片を取り出すために、明示的に stream.read() を呼び出す必要があります。 ストリームは paused モードから始まります。

注意: もし 'data' イベントハンドラが割り当てられてなく、 pipe() の出力先もなく、そしてストリームが flowing モードに 切り替わると、データは失われます。

以下のいずれかで flowing に切り替えることができます。

  • データを監視するために 'data' イベント ハンドラを追加する。
  • 明示的にデータのフローを開始するために resume() を呼び出す。
  • Writable にデータを送るために pipe() を呼び出す。

以下のいずれかで paused モードに戻すことができます。

  • パイプの出力先がなければ、pause() メソッドを呼び出します。
  • パイプの出力先があるなら、'data' イベント のハンドラを削除し、 unpipe() メソッドを呼び出して全てのパイプ出力先を削除します。

互換性の理由から、'data' イベントのハンドラを削除してもストリームは 自動的には中断 しない ことに注意してください。 同様に、パイプの出力先があると、それらの出力先が空になるとより多くのデータを 要求するため、pause() を呼び出してもストリームが中断した まま であることは 保証されません。

Readable ストリームを含む例:

Event: 'readable'#

ストリームからデータの断片を読み込むことが可能となった時、 'readable' イベントが生成されます。

あるケースでは、'readable' イベントを監視することは下層のシステムからデータを内部バッファへ読み込む原因となります (それがまだ行われていなかった場合)。

var readable = getReadableStreamSomehow();
readable.on('readable', function() {
  // there is some data to read now
})

内部バッファが空になると、データが利用可能になった時に 'readable' イベントは再び生成されます。

Event: 'data'#

  • chunk {Buffer | String} データの断片。

'data' イベントのリスナをストリームに追加すると、明示的に中断されるまで ストリームは flowing モードに切り替わります。 データは利用可能になるとすぐにあなたのハンドラに渡されます。

ストリームから出てくる全てのデータをできるだけ素早く欲しいのなら、 これが最善の方法です。

var readable = getReadableStreamSomehow();
readable.on('data', function(chunk) {
  console.log('got %d bytes of data', chunk.length);
})

Event: 'end'#

このイベントは、提供するデータがもう無くなった場合に生成されます。

'end' イベントはデータが完全に消費されるまでは 生成されない ことに注意してください。 それは flowing モードに切り替えることによって、または終わりに達するまで read() を繰り返し呼び出すことによって達成することができます。

var readable = getReadableStreamSomehow();
readable.on('data', function(chunk) {
  console.log('got %d bytes of data', chunk.length);
})
readable.on('end', function() {
  console.log('there will be no more data.');
});

Event: 'close'#

下層のリソース (例えば背後のファイル記述子) がクローズされた時に生成されます。 全てのストリームがこのイベントを発生するわけではありません。

Event: 'error'#

データの受信でエラーがあると生成されます。

readable.read([size])#

  • size {Number} どれだけのデータを読み込むか指定するオプションの引数。
  • Return {String | Buffer | null}

read() メソッドは内部バッファからデータを取り出して返します。 もし利用可能なデータが無ければ、null を返します。

size 引数を指定すると、その長さ (バイト数または文字数) のデータを返します。 もし size で指定された長さのデータが揃っていない場合は null を返します。

size 引数を指定しなかった場合は、内部バッファにある全てのデータが返されます。

このメソッドは paused モードの場合に限って呼び出されるべきです。 flowing モードでは、内部バッファが空になるまで このメソッドは自動的に呼び出されます。

var readable = getReadableStreamSomehow();
readable.on('readable', function() {
  var chunk;
  while (null !== (chunk = readable.read())) {
    console.log('got %d bytes of data', chunk.length);
  }
});

もしこのメソッドがデータの断片を返すと、それは 'data' イベント の 生成も引き起こします。

readable.setEncoding(encoding)#

  • encoding {String} 使用するエンコーディング。

この関数を呼び出すと、ストリームは Buffer オブジェクトの代わりに 指定されたエンコーディングによる文字列を返すようになります。 例えば、readable.setEncoding('utf8') とすると、得られるデータは UTF-8 のデータとして解釈され、文字列が返されます。 readable.setEncoding('hex') とすると、データは 16 進フォーマットの 文字列にエンコードされます。

これは、Buffer を直接取得して単純に buf.toString(encoding) を呼び出した場合は潜在的にめちゃくちゃになるのとは異なり、 マルチバイト文字を正しく扱います。 データを文字列として読み込みたければ、常にこのメソッドを使用してください。

var readable = getReadableStreamSomehow();
readable.setEncoding('utf8');
readable.on('data', function(chunk) {
  assert.equal(typeof chunk, 'string');
  console.log('got %d characters of string data', chunk.length);
})

readable.resume()#

  • Return: this

このメソッドは Readable ストリームが 'data' イベントの生成を 再開するようにします。

このメソッドはストリームを flowing モードに切り替えます。 もしストリームからのデータを消費する必要が なく、しかし 'end' イベントを 受け取る必要が ある なら、readable.resume() を呼び出してデータの フローを開くことができます。

var readable = getReadableStreamSomehow();
readable.resume();
readable.on('end', function(chunk) {
  console.log('got to the end, but did not read anything');
})

readable.pause()#

  • Return: this

このメソッドはストリームを flowing モードに切り替えて、 'data' イベントの生成を中断します。 利用可能になったデータは内部バッファの中に残ったままとなります。

var readable = getReadableStreamSomehow();
readable.on('data', function(chunk) {
  console.log('got %d bytes of data', chunk.length);
  readable.pause();
  console.log('there will be no more data for 1 second');
  setTimeout(function() {
    console.log('now data will start flowing again');
    readable.resume();
  }, 1000);
})

readable.pipe(destination, [options])#

  • destination {Writable Stream} データの書き込み先。
  • options {Object} パイプオプション
    • end {Boolean} 読み込み元が終了すると書き込み先を終了します。 デフォルトは true

このメソッドは Readable ストリームから全てのデータを引き出し、 与えられた行き先に書き込みます。 高速な Readable ストリームによって出力先が圧迫されないように、 自動的にフロー制御を行います。

複数の出力先を安全に連結することができます。

var readable = getReadableStreamSomehow();
var writable = fs.createWriteStream('file.txt');
// All the data from readable goes into 'file.txt'
readable.pipe(writable);

この関数は出力先となるストリーム返すので、このようにパイプのチェーンを 組み立てることができます。

var r = fs.createReadStream('file.txt');
var z = zlib.createGzip();
var w = fs.createWriteStream('file.txt.gz');
r.pipe(z).pipe(w);

Unix の cat コマンドをエミュレートする例:

process.stdin.pipe(process.stdout);

デフォルトでは、出力先の end() は入力元のストリームで 'end' が生成された時に呼び出されます。そのため、destination はもう書き込み可能ではなくなります。 {end: false }options として渡すことにより、出力先ストリームを オープンしたままにしておくことができます。

これは writer をオープンしたままにすることにより、最後に "Goodbye" と書き込むことができます。

reader.pipe(writer, { end: false });
reader.on('end', function() {
  writer.end('Goodbye\n');
});

process.stderr および process.stdout は、オプションの指定に関係なく、 プロセスが終了するまで決してクローズされないことに注意してください。

readable.unpipe([destination])#

  • destination {Writable Stream} オプションのパイプを解除するストリーム

このメソッドは以前の pipe() 呼び出しで設定されたフックを取り除きます。

destination が指定されなかった場合は、全てのパイプが取り除かれます。

destination が指定されたものの、それがパイプされていなかった場合、 これは何もしません。

var readable = getReadableStreamSomehow();
var writable = fs.createWriteStream('file.txt');
// All the data from readable goes into 'file.txt',
// but only for the first second
readable.pipe(writable);
setTimeout(function() {
  console.log('stop writing to file.txt');
  readable.unpipe(writable);
  console.log('manually close the file stream');
  writable.end();
}, 1000);

readable.unshift(chunk)#

  • chunk {Buffer | String} 読み込みキューの先頭に戻されるデータの断片

これはストリームがパーサによって消費されるケースにおいて有用です。 それはソースから楽観的に取り出したデータを「消費しなかった」ことにして、 ストリームが他のところにデータを渡せるようにする場合に必要です。

stream.unshift(chunk) を頻繁に呼び出さなくてはならないとしたら、 代わりに Transform ストリームを実装することを検討してください (後述する ストリーム実装者向けの API を参照してください)。

// Pull off a header delimited by \n\n
// use unshift() if we get too much
// Call the callback with (error, header, stream)
var StringDecoder = require('string_decoder').StringDecoder;
function parseHeader(stream, callback) {
  stream.on('error', callback);
  stream.on('readable', onReadable);
  var decoder = new StringDecoder('utf8');
  var header = '';
  function onReadable() {
    var chunk;
    while (null !== (chunk = stream.read())) {
      var str = decoder.write(chunk);
      if (str.match(/\n\n/)) {
        // found the header boundary
        var split = str.split(/\n\n/);
        header += split.shift();
        var remaining = split.join('\n\n');
        var buf = new Buffer(remaining, 'utf8');
        if (buf.length)
          stream.unshift(buf);
        stream.removeListener('error', callback);
        stream.removeListener('readable', onReadable);
        // now the body of the message can be read from the stream.
        callback(null, header, stream);
      } else {
        // still reading the header.
        header += str;
      }
    }
  }
}

readable.wrap(stream)#

  • stream {Stream} 「古いスタイル」の Readable ストリーム

v0.10 より前のバージョンの Node には、今日の全ストリーム API を実装していない ストリームがありました (より詳細は後述する「互換性」を参照してください)。

もし、'data' イベントを生成し、アドバイスだけを行う pause() メソッドを持つ、古い Node ライブラリを使っているなら、 wrap() メソッドは古いストリームをデータソースとして使用する Readable ストリームを作成します。

この関数を呼び出す必要は滅多にありませんが、これは古い Node プログラム及びライブラリと相互作用するための利便性のために存在します。

例:

var OldReader = require('./old-api-module.js').OldReader;
var oreader = new OldReader;
var Readable = require('stream').Readable;
var myReader = new Readable().wrap(oreader);

myReader.on('readable', function() {
  myReader.read(); // etc.
});

Class: stream.Writable#

Writable ストリームのインターフェースは、あなたがデータを書き込む抽象的な 行き先 です。

Writable ストリームを含む例:

writable.write(chunk, [encoding], [callback])#

  • chunk {String | Buffer} 書き込まれるデータ
  • encoding {String} もし chunk が文字列なら、そのエンコーディング
  • callback {Function} データが掃き出された時に呼び出されるコールバック
  • Returns: {Boolean} データが完全に処理された場合は true

このメソッドはデータを下層のシステムに書き込み、データが完全に処理されると 与えられたコールバックを一度だけ呼び出します。

戻り値は書き込みをすぐに続けていいかどうかを示します。 もしデータが内部にバッファリングされなければならないなら false を返します。 そうでなければ true を返します。

この戻り値は完全にアドバイス的です。 もしこれが false を返しても、あなたは書き込みを続けることが「できます」。 しかしながら、書き込まれたデータはメモリにバッファリングされるため、 これを過剰にしないことが最善です。 代わりに、より多くのデータを書く前に 'drain' イベントを待機してください。

Event: 'drain'#

write(chunk, encoding, callback) の呼び出しが false を返した場合、 より多くのデータをいつストリームに書き始めるのが適切かを 'drain' イベントによって示します。

// Write the data to the supplied writable stream 1MM times.
// Be attentive to back-pressure.
function writeOneMillionTimes(writer, data, encoding, callback) {
  var i = 1000000;
  write();
  function write() {
    var ok = true;
    do {
      i -= 1;
      if (i === 0) {
        // last time!
        writer.write(data, encoding, callback);
      } else {
        // see if we should continue, or wait
        // don't pass the callback, because we're not done yet.
        ok = writer.write(data, encoding);
      }
    } while (i > 0 && ok);
    if (i > 0) {
      // had to stop early!
      // write some more once it drains
      writer.once('drain', write);
    }
  }
}

writable.cork()#

全ての書き込みをバッファリングするように強制します。

バッファリングされたデータは .uncork() または .end() のいずれかが 呼び出されるとフラッシュされます。

writable.uncork()#

.cork() が呼び出されてからバッファリングされたデータをフラッシュします。

writable.end([chunk], [encoding], [callback])#

  • chunk {String | Buffer} オプションの書き込まれるデータ
  • encoding {String} もし chunk が文字列なら、そのエンコーディング
  • callback {Function} ストリームが終了時に呼び出される、 オプションのコールバック

これ以上データをストリームに書き込まない場合に呼び出してください。 コールバックが与えられた場合、それは 'finish' イベントのリスナとして アタッチされます。

end() を呼び出した後で write() を呼び出すとエラーになります。

// write 'hello, ' and then end with 'world!'
http.createServer(function (req, res) {
  res.write('hello, ');
  res.end('world!');
  // writing more now is not allowed!
});

Event: 'finish'#

end() メソッドが呼び出されて、全てのデータが下層のシステムに 掃き出されると、このイベントが生成されます。

var writer = getWritableStreamSomehow();
for (var i = 0; i < 100; i ++) {
  writer.write('hello, #' + i + '!\n');
}
writer.end('this is the end\n');
writer.on('finish', function() {
  console.error('all writes are now complete.');
});

Event: 'pipe'#

  • src {Readable Stream} この Writable ストリームにつながれた 入力元のストリーム

これは、Readable ストリームの pipe() メソッドが呼び出されて、 この Writable ストリームが出力先として加えられた時に生成されます。

var writer = getWritableStreamSomehow();
var reader = getReadableStreamSomehow();
writer.on('pipe', function(src) {
  console.error('something is piping into the writer');
  assert.equal(src, reader);
});
reader.pipe(writer);

Event: 'unpipe'#

これは、Readable ストリームで unpipe() メソッドが呼び出され、 この Writable ストリームが出力先から取り除かれた時に生成されます。

var writer = getWritableStreamSomehow();
var reader = getReadableStreamSomehow();
writer.on('unpipe', function(src) {
  console.error('something has stopped piping into the writer');
  assert.equal(src, reader);
});
reader.pipe(writer);
reader.unpipe(writer);

Event: 'error'#

データの書き込みまたはデータのパイプ中にエラーがあると生成されます。

Class: stream.Duplex#

Duplex ストリームは ReadableWritable 両方のインターフェースを 実装したストリームです。使い方は上記を参照してください。

Duplex ストリームを含む例:

Class: stream.Transform#

Transform ストリームは、入力から何らかの方法で出力が計算される Duplex ストリームです。 それらは ReadableWritable 両方のインターフェースを実装します。 使い方は上記を参照してください。

Transform ストリームを含む例:

API for Stream Implementors#

どのストリームを実装する場合でも、パターンは同じです:

  1. それぞれの親クラスを拡張して、独自のサブクラスを作成する (特に util.inherits メソッドはそのために役立ちます)。
  2. 内部のメカニズムがきちんとセットアップされることを確実にするために、 サブクラスのコンストラクタの中から親クラスのコンストラクタを呼び出す。
  3. 以下で詳述される、いくつかの特別なメソッドを実装する。

拡張するクラスと実装するメソッドは、あなたが書こうとしているストリームの種類に 依存します。

ユースケース

クラス

実装するメソッド

読み込みのみ

Readable

_read

書き込みのみ

Writable

_write

読み込みと書き込み

Duplex

_read, _write

書き込まれたデータを変換し、その結果を読み込む

Transform

_transform, _flush

あなたの実装コードの中では、決して ストリーム利用者のための API で説明されたメソッドを呼び出さないことがとても重要です。 そうでなければ、あなたのストリーミングインターフェースを利用するプログラムに 有害な副作用を引き起こす原因となり得ます。

Class: stream.Readable#

stream.Readable は抽象クラスで、下層の実装として _read(size) メソッドを実装することで拡張されるように設計されています。

プログラムの中で Readable ストリームを利用する方法については、 前述の ストリーム利用者のための API を参照してください。 この後に続くのは、あなたのプログラムの中で Readable ストリームを 実装する方法の説明です。

Example: A Counting Stream#

これは Readable ストリームの基本的な例です。 それは 1 から 1,000,000 までの数を昇順で生成し、そして終了します。

var Readable = require('stream').Readable;
var util = require('util');
util.inherits(Counter, Readable);

function Counter(opt) {
  Readable.call(this, opt);
  this._max = 1000000;
  this._index = 1;
}

Counter.prototype._read = function() {
  var i = this._index++;
  if (i > this._max)
    this.push(null);
  else {
    var str = '' + i;
    var buf = new Buffer(str, 'ascii');
    this.push(buf);
  }
};

Example: SimpleProtocol v1 (Sub-optimal)#

これは前に説明した parseHeader 関数とよく似ていますが、 独自のストリームとして実装されています。 また、この実装は入ってくるデータを文字列に変換しないことに注意してください。

しかしながら、これは Transform ストリームを使うことでよりうまく実装できます。 後述のよりよい実装を参照してください。

// A parser for a simple data protocol.
// The "header" is a JSON object, followed by 2 \n characters, and
// then a message body.
//
// NOTE: This can be done more simply as a Transform stream!
// Using Readable directly for this is sub-optimal.  See the
// alternative example below under the Transform section.

var Readable = require('stream').Readable;
var util = require('util');

util.inherits(SimpleProtocol, Readable);

function SimpleProtocol(source, options) {
  if (!(this instanceof SimpleProtocol))
    return new SimpleProtocol(source, options);

  Readable.call(this, options);
  this._inBody = false;
  this._sawFirstCr = false;

  // source is a readable stream, such as a socket or file
  this._source = source;

  var self = this;
  source.on('end', function() {
    self.push(null);
  });

  // give it a kick whenever the source is readable
  // read(0) will not consume any bytes
  source.on('readable', function() {
    self.read(0);
  });

  this._rawHeader = [];
  this.header = null;
}

SimpleProtocol.prototype._read = function(n) {
  if (!this._inBody) {
    var chunk = this._source.read();

    // if the source doesn't have data, we don't have data yet.
    if (chunk === null)
      return this.push('');

    // check if the chunk has a \n\n
    var split = -1;
    for (var i = 0; i < chunk.length; i++) {
      if (chunk[i] === 10) { // '\n'
        if (this._sawFirstCr) {
          split = i;
          break;
        } else {
          this._sawFirstCr = true;
        }
      } else {
        this._sawFirstCr = false;
      }
    }

    if (split === -1) {
      // still waiting for the \n\n
      // stash the chunk, and try again.
      this._rawHeader.push(chunk);
      this.push('');
    } else {
      this._inBody = true;
      var h = chunk.slice(0, split);
      this._rawHeader.push(h);
      var header = Buffer.concat(this._rawHeader).toString();
      try {
        this.header = JSON.parse(header);
      } catch (er) {
        this.emit('error', new Error('invalid simple protocol data'));
        return;
      }
      // now, because we got some extra data, unshift the rest
      // back into the read queue so that our consumer will see it.
      var b = chunk.slice(split);
      this.unshift(b);

      // and let them know that we are done parsing the header.
      this.emit('header', this.header);
    }
  } else {
    // from there on, just provide the data to our consumer.
    // careful not to push(null), since that would indicate EOF.
    var chunk = this._source.read();
    if (chunk) this.push(chunk);
  }
};

// Usage:
// var parser = new SimpleProtocol(source);
// Now parser is a readable stream that will emit 'header'
// with the parsed header data.

new stream.Readable([options])#

  • options {Object} (任意)
    • highWaterMark {Number} 下層のリソースから読み込むのを中断するまで 内部バッファに貯めておくバイト数の最大値。 デフォルトは 16kb、あるいは objectMode では 16。
    • encoding {String} 指定されるとバッファは指定のエンコーディングで デコードされます。デフォルトは null
    • objectMode {Boolean} このストリームがオブジェクトストリームとして 振る舞うべきかどうか。これは stream.read(n) がサイズ n のバッファではなく 一つの値を返すことを意味します。デフォルトは false

Readable クラスを拡張するクラスでは、バッファリングの設定を確実に 初期化することができるように、必ずコンストラクタを呼び出してください。

readable._read(size)#

  • size {Number} 非同期に読み込むバイト数

注意: この関数を実装してください、しかし直接呼び出さないでください。

この関数は直接呼び出すべきではありません。 これはサブクラスで実装されるべきであり、Readable クラスの内部から 呼び出されるべきです。

全ての Readable ストリームは、下層のリソースからデータを 取得するために _read() メソッドを提供しなければなりません。

このメソッドはこれを定義するクラス内部のものであり、ユーザプログラムから 直接呼び出されるべきものではないため、アンダースコアの接頭辞を持ちます。 しかしながら、あなたの拡張クラスではこのメソッドをオーバーライドすることが 求められています。

データが利用可能になれば、readable.push(chunk) を呼び出すことで それを読み込みキューに追加します。 push() が false を返した場合は、読み込みを止めるべきです。 _read() が再び呼び出された時が、さらに多くのデータを追加を開始すべき時です。

size 引数はアドバイス的です。 "read()" が一回の呼び出しでデータを返す実装では、 どれだけのデータを取得すべきか知るためにこれを使うことができます。 TCPやTLSなど、それに関連しない実装ではこの引数は無視され、 利用可能になったデータをシンプルに提供するかもしれません。 たとえば stream.push(chunk) が呼び出されるより前に、 size バイトが利用可能になるまで「待つ」必要はありません。

readable.push(chunk, [encoding])#

  • chunk {Buffer | null | String} 読み込みキューにプッシュされる、 データのチャンク
  • encoding {String} 文字列チャンクのエンコーディング。 'utf8''ascii' など、Buffer の正しいエンコーディングの必要があります。
  • return {Boolean} さらにプッシュしてもいいかどうか

注意: この関数は Readable の実装から呼び出されるべきものであり、 Readable ストリームの利用者が呼び出すべきではありません。

少なくとも一回は push(chunk) が呼び出されないと、_read() 関数が 再び呼び出されることはありません。

Readable クラスは、read() メソッドが呼び出されることで 後から取り出されるデータを、'readable' イベントの生成時に 読み込みキューに入れておくことによって機能します。

push() メソッドはいくつかのデータを明示的に読み込みキューに挿入します。 もし null と共に呼び出されると、それはデータが終了した (EOF) ことを伝えます。

この API は可能な限り柔軟に設計されています。 例えば、ある種の中断/再開メカニズムとデータのコールバックを持つ、 より低水準のデータソースをラップするかもしれません。 それらのケースでは、このように低水準のソースオブジェクトを ラップすることができます。

// source is an object with readStop() and readStart() methods,
// and an `ondata` member that gets called when it has data, and
// an `onend` member that gets called when the data is over.

util.inherits(SourceWrapper, Readable);

function SourceWrapper(options) {
  Readable.call(this, options);

  this._source = getLowlevelSourceObject();
  var self = this;

  // Every time there's data, we push it into the internal buffer.
  this._source.ondata = function(chunk) {
    // if push() returns false, then we need to stop reading from source
    if (!self.push(chunk))
      self._source.readStop();
  };

  // When the source ends, we push the EOF-signalling `null` chunk
  this._source.onend = function() {
    self.push(null);
  };
}

// _read will be called when the stream wants to pull more data in
// the advisory size argument is ignored in this case.
SourceWrapper.prototype._read = function(size) {
  this._source.readStart();
};

Class: stream.Writable#

stream.Writable は抽象クラスで、下層の実装として _write(chunk, encoding, callback) メソッドを実装することで 拡張されるように設計されています。

プログラムの中で Writable ストリームを利用する方法については、 前述の ストリーム利用者のための API を参照してください。 この後に続くのは、あなたのプログラムの中で Writable ストリームを 実装する方法の説明です。

new stream.Writable([options])#

  • options {Object} (任意)
    • highWaterMark {Number} write()false を返し始める バッファレベル。デフォルトは 16kb、あるいは objectMode では 16。
    • decodeStrings {Boolean} 文字列が _write() に渡される前に バッファにデコードするかどうか。デフォルトは true

Writable クラスを拡張するクラスでは、バッファリングの設定を確実に 初期化することができるように、必ずコンストラクタを呼び出してください。

writable._write(chunk, encoding, callback)#

  • chunk {Buffer | Array} 書き込まれるデータ。 decodeStrings オプションが false に設定されない限り常にバッファです。
  • encoding {String} チャンクが文字列の場合のエンコーディング方式。 チャンクがバッファの場合は無視されます。 decodeStrings オプションが明示的に false に設定されない限り、 チャンクは 常に バッファであるべき事に注意してください。
  • callback {Function} チャンクを提供する処理が終了した時に、 (任意のエラー引数と共に) この関数を呼び出してください。

全ての Writable ストリームは、下層のリソースにデータを 送るために _write() メソッドを提供しなければなりません。

注意: この関数は直接呼び出してはいけません。 これはサブクラスで実装されるべきであり、Writable クラスの内部からのみ 呼び出されるべきです。

コールバックは出力が成功して完了したか、エラーが発生したかを伝えるために、 標準的な callback(error) パターンを使って呼び出します。

コンストラクタオプションの decodeStrings フラグがセットされると、 chunk を Buffer ではなく文字列にし、encoding でその文字列の 種類を示すことができます。 これは、実装が文字列データのエンコーディングを最適化できるようにするためです。 decodeStrings オプションを明示的に false に設定しない場合、 endocing 引数は安全に無視することができます。 そして chunk は常に Buffer であると見なせます。

このメソッドはこれを定義するクラス内部のものであり、ユーザプログラムから 直接呼び出されるべきものではないため、アンダースコアの接頭辞を持ちます。 しかしながら、あなたの拡張クラスではこのメソッドをオーバーライドすることが 求められています。

writable._writev(chunks, callback)#

  • chunks {Array} 書き込まれるチャンクの配列。 それぞれのチャンクは 以下のフォーマット: { chunk: ..., encoding: ... }
  • callback {Function} 与えられたチャンクの処理が完了すると、この関数が (オプションのエラー引数を伴って) 呼び出されます。

注意: この関数は直接呼び出しては いけません**。 これはおそらくサブクラスによって実装され、 Writable クラス内部のメソッドによってのみ呼び出されます。

この関数の実装は完全に任意です。ほとんどのケースでは必要ありません。 もし実装されると、書き込みキューにバッファリングされた全ての断片と共に 呼び出されます。

Class: stream.Duplex#

"duplex" ストリームは、TCP ソケットコネクションのように Readable であり Writable でもあるストリームの一種です。

stream.Duplex は、Readable および Writable ストリームクラスと同様、 下層の実装である _read(size) および _write(chunk, encoding, callback) メソッドによって拡張されるように 設計された抽象クラスであることに注意してください。

JavaScript は複数のプロトタイプ継承を持つことができないため、 このクラスは Readable からプロトタイプを継承したうえで、 Writable から寄生的な方法 (プロトタイプメンバーのコピー) を行います。 低水準の _read(size) および _write(chunk, encoding, callback) を実装することは、Duplex クラスを拡張するユーザの責務です。

new stream.Duplex(options)#

  • options {Object} Writable および Readable のコンストラクタに渡されます。 以下のフィールドを持つこともできます:
    • allowHalfOpen {Boolean} デフォルトは true。 もし false に設定された場合、読み込み側が閉じられると 自動的に書き込み側も閉じられます。

Duplex クラスを拡張するクラスでは、バッファリングの設定を確実に 初期化することができるように、必ずコンストラクタを呼び出してください。

Class: stream.Transform#

"Transform" ストリームは、zlib ストリームや crypto ストリームのように、 入力が何らかの方法で出力の元となっているような Duplex ストリームです。

出力は、入力と同じサイズ、同じ数のチャンク、同時に到着することを 要求されません。 たとえば、Hash ストリームは入力が終了すると一つだけのチャンクを出力します。 zlib ストリームは、入力より小さいか、またはより大きい出力を生成します。

_read() および _write() メソッドの代わりに、Transform クラスでは _transform() メソッドを実装しなければなりません。 また、任意で _flush() メソッドを実装することもできます (後述)。

new stream.Transform([options])#

  • options {Object} Writable および Readable のコンストラクタに渡されます。

Transform クラスを拡張するクラスでは、バッファリングの設定を確実に 初期化することができるように、必ずコンストラクタを呼び出してください。

transform._transform(chunk, encoding, callback)#

  • chunk {Buffer | Array} 書き込まれるデータ。 decodeStrings オプションが false に設定されない限り常にバッファです。
  • encoding {String} チャンクが文字列の場合のエンコーディング方式 (チャンクがバッファの場合は無視されます)。
  • callback {Function} チャンクを提供する処理が終了した時に、 (任意のエラー引数と共に) この関数を呼び出してください。

注意: この関数は直接呼び出してはいけません。 これはサブクラスで実装されるべきであり、Transform クラスの内部からのみ 呼び出されるべきです。

全ての Transform ストリームの実装は、入力を受け取って出力を提供するために _transform() メソッドを提供しなければなりません。

書き込まれるバイトを処理し、読み込み可能なインタフェースに渡すなど、 Transform クラスでしなければならないことは全て _transform() で行わなければなりません。非同期 I/O、何かの処理、その他。

この入力チャンクからの出力を生成するために、transform.push(outputChunk) を 0 回以上呼び出してください。 それはこのチャンクの結果としてどれだけのデータを出力したいのかに依存します。

現在のチャンクの処理が完全に終了した場合のみ、コールバック関数を呼び出します。 特定の入力チャンクからの結果として、出力があるかもしれないし、 無いかもしれないことに注意してください。

このメソッドはこれを定義するクラス内部のものであり、ユーザプログラムから 直接呼び出されるべきものではないため、アンダースコアの接頭辞を持ちます。 しかしながら、あなたの拡張クラスではこのメソッドをオーバーライドすることが 求められています。

transform._flush(callback)#

  • callback {Function} 与えられたチャンクの処理が終了した場合に、 (任意のエラー引数と共に) この関数を呼び出してください。

注意: この関数は直接呼び出してはいけません。 これはサブクラスで実装されるかもしれず、Transform クラスの内部からのみ 呼び出されるべきです。

場合によっては、変換操作はストリームの終端でより多くのデータを 生成する必要があります。 たとえば、Zlib 圧縮ストリームは出力を最適に圧縮できるように、 いくつかの内部状態を持ちます。 一方、終端ではデータが完全なものになるように、 残されたものに最善を尽くす必要があります。

この場合、最後の最後 (書き込まれた全てのデータが消費された後、 ただし読み込み側の終了を知らせる 'end' が生成される前) に呼び出される _flush() メソッドを実装することができます。 _transform() と同様、transform.push(chunk) を何度 (0 回以上) でも 適切に呼び出し、フラッシュ操作が完了した時に callback を呼び出します。

このメソッドはこれを定義するクラス内部のものであり、ユーザプログラムから 直接呼び出されるべきものではないため、アンダースコアの接頭辞を持ちます。 しかしながら、あなたの拡張クラスではこのメソッドをオーバーライドすることが 求められています。

Example: SimpleProtocol parser v2#

前述した単純なプロトコルパーサの例は、より高水準な Transform ストリームクラスを 使うことで、さらにシンプルに実装することができます。 前述の parseHeader および SimpleProtocol v1 とよく似た例です。

この例では、入力を引数で与えるのではなく、Node のストームにおける より慣用的なアプローチとしてパーサにパイプで送られます。

var util = require('util');
var Transform = require('stream').Transform;
util.inherits(SimpleProtocol, Transform);

function SimpleProtocol(options) {
  if (!(this instanceof SimpleProtocol))
    return new SimpleProtocol(options);

  Transform.call(this, options);
  this._inBody = false;
  this._sawFirstCr = false;
  this._rawHeader = [];
  this.header = null;
}

SimpleProtocol.prototype._transform = function(chunk, encoding, done) {
  if (!this._inBody) {
    // check if the chunk has a \n\n
    var split = -1;
    for (var i = 0; i < chunk.length; i++) {
      if (chunk[i] === 10) { // '\n'
        if (this._sawFirstCr) {
          split = i;
          break;
        } else {
          this._sawFirstCr = true;
        }
      } else {
        this._sawFirstCr = false;
      }
    }

    if (split === -1) {
      // still waiting for the \n\n
      // stash the chunk, and try again.
      this._rawHeader.push(chunk);
    } else {
      this._inBody = true;
      var h = chunk.slice(0, split);
      this._rawHeader.push(h);
      var header = Buffer.concat(this._rawHeader).toString();
      try {
        this.header = JSON.parse(header);
      } catch (er) {
        this.emit('error', new Error('invalid simple protocol data'));
        return;
      }
      // and let them know that we are done parsing the header.
      this.emit('header', this.header);

      // now, because we got some extra data, emit this first.
      this.push(chunk.slice(split));
    }
  } else {
    // from there on, just provide the data to our consumer as-is.
    this.push(chunk);
  }
  done();
};

// Usage:
// var parser = new SimpleProtocol();
// source.pipe(parser)
// Now parser is a readable stream that will emit 'header'
// with the parsed header data.

Class: stream.PassThrough#

これは Transform ストリームの取るに足らない実装で、 入力したバイト列を出力に単純に渡すだけです。 これの主な目的はサンプル及びテストですが、新しい種類のストリームのための ビルディングブロックとして、何かと便利となるユースケースが時折存在します。

Streams: Under the Hood#

Buffering#

Readable 及び Writable ストリームはそれぞれ、_writableState.buffer または _readableState.buffer と呼ばれる内部オブジェクトにデータを バッファリングします。

バッファリングされるデータの量は、コンストラクタに渡される highWaterMark オプションに依存します。

Readable ストリームにおけるバッファリングは、実装が stream.push(chunk) を呼び出した時に起こります。 ストリームの利用者が stream.read() を呼び出さないと、 データはそれが消費されるまで内部キューに留まります。

Writable ストリームにおけるバッファリングは、利用者が stream.write(chunk) を繰り返し呼び出すと、write()false を返した場合でも起こります。

ストリーム、特に pipe() メソッドの目的は、データのバッファリングを 許容できるレベルに制限することです。そのため、様々な速度の入力元と出力先で、 利用可能なメモリを圧迫しません。

stream.read(0)#

実際にデータを消費することなく、下層の Readable ストリームのメカニズムを リフレッシュするきっかけが欲しくなるケースがあります。 そのケースでは、常に null を返す stream.read(0) を呼び出すことができます。

内部バッファが highWaterMark を下回っていて、 ストリームが現在読み込み中でなければ、read(0) の呼び出しは低水準の _read() を呼び出すきっかけとなります。

これをする必要はほとんどありません。 しかしながら Node の内部、特に Readable ストリームクラスの内部で、 これが使われているケースを見ることができるでしょう。

stream.push('')#

ゼロバイトの長さの文字列またはバッファをプッシュすると、 (オブジェクトモードの場合を除き) 面白い副作用が起こります。 それは stream.push() を呼び出すので、reading プロセスを終了します。 しかしながら、それは読み込みバッファにどんなデータも加え ない ので、 ユーザが消費するものは何もありません。

ごくまれに、今は提供するデータが無い場合があります。しかし、stream.read(0) を呼び出すことにより、ストリームの利用者 (あるいは、もしかするとあなたの コードの一部) は再びチェックすべきなのがいつかを知ることができます。 このケースでは、stream.push('') を呼び出すことが できます

現在の所、この機能の唯一のユースケースは v0.12 で廃止予定の tls.CryptoStream の中にあります。 もし stream.push('') を使わなければならないことになったら、それはおそらく 何かが恐ろしく間違っていることを示すので、他の方法を検討してください。

Compatibility with Older Node Versions#

v0.10 より前のバージョンの Node では、Readable ストリームのインタフェースは よりシンプルでしたが、強力ではなく使いやすくもありませんでした。

  • read() メソッドが呼び出されるのを待つのではなく、 'data' イベントがすぐに生成され始めます。 もしデータを処理する方法を決定するためにいくらかの I/O をする 必要がある場合、データが失われないようにするためには チャンクを何らかのバッファに保存しなければなりませんでした。
  • pause() は保証というよりはむしろ助言でした。 それはストリームが中断された状態であったとしても、 'data' イベントを受け取る準備が必要だということを意味します。

Node v0.10 から、上記で説明した Readable クラスが追加されました。 古い Node プログラムとの後方互換性のために、Readable ストリームは 'data' イベントのハンドラが加えられた場合や、 resume() メソッドが読み出されると、「flowing モード」に切り替わります。 その結果として、新しい read() メソッドや 'readable' イベントを 使用していなくても、もう 'data' イベントのチャンクが失われることを 心配する必要はありません。

ほとんどのプログラムはこれまで通りに機能するでしょう。 しかしながら、以下の条件でエッジケースが存在します。

  • 'data' イベント イベントハンドラが登録されていない。
  • resume() メソッドが呼び出されていない。
  • ストリームはどの書き込みストリームへもパイプされていない。

例えば、以下のコードを考えてみてください:

// WARNING!  BROKEN!
net.createServer(function(socket) {

  // we add an 'end' method, but never consume the data
  socket.on('end', function() {
    // It will never get here.
    socket.end('I got your message (but didnt read it)\n');
  });

}).listen(1337);

v0.10 より前の Node では、入ってきたデータは単純に破棄されていました。 しかしながら、Node v0.10 以降では、ソケットは中断したままとなります。

この状況の回避策は、データの流れを開始するために resume() メソッドを呼び出すことです。

// Workaround
net.createServer(function(socket) {

  socket.on('end', function() {
    socket.end('I got your message (but didnt read it)\n');
  });

  // start the flow of data, discarding it.
  socket.resume();

}).listen(1337);

新しい Readable ストリームを flowing モードに切り替えられることに加えて、 wrap() メソッドを使って v0.10 より前のスタイルのストリームを Readable クラスでラップすることもできます。

Object Mode#

通常、ストリームは文字列またはバッファのみを扱います。

オブジェクトモード のストリームは、文字列及びバッファ以外の 一般的なJavaScriptの値を扱うことができます。

オブジェクトモードの Readable ストリームは、stream.read(size) のサイズ引数が いくつであるかに関わらず、常に一つの項目を返します。

オブジェクトモードの Writable ストリームは、stream.write(data, encoding)encoding 引数を常に無視します。

特別な値 null は、オブジェクトモードのストリームにおいても 特別な値を持ちます。 すなわち、オブジェクトモードの Readable ストリームでは、stream.read() の戻り値 null はもうデータが無いことを、stream.push(null) はストリームデータの終端を示します (EOF)。

Node のコアライブラリにはオブジェクトモードのストリームは存在しません。 このパターンはユーザランドのライブラリでのみ使われます。

ストリームのサブクラスはコストラクタの options オブジェクトで objectMode を設定すべきです。 objectMode をストリームの途中で設定することは安全ではありません。

State Objects#

Readable ストリームは _readableState と呼ばれるメンバを持っています。 Writable ストリームは _writableState と呼ばれるメンバを持っています。 Duplex ストリームは両方を持っています。

通常、これらのオブジェクトはサブクラスで変更すべきではありません。 しかしながら、もし Duplex または Transform ストリームの読み込み側が objectMode で、書き込み側が objectMode ではない場合、コンストラクタで 適切なステートオブジェクトにフラグを明示的に設定することになるかもしれません。

var util = require('util');
var StringDecoder = require('string_decoder').StringDecoder;
var Transform = require('stream').Transform;
util.inherits(JSONParseStream, Transform);

// Gets \n-delimited JSON string data, and emits the parsed objects
function JSONParseStream(options) {
  if (!(this instanceof JSONParseStream))
    return new JSONParseStream(options);

  Transform.call(this, options);
  this._writableState.objectMode = false;
  this._readableState.objectMode = true;
  this._buffer = '';
  this._decoder = new StringDecoder('utf8');
}

JSONParseStream.prototype._transform = function(chunk, encoding, cb) {
  this._buffer += this._decoder.write(chunk);
  // split on newlines
  var lines = this._buffer.split(/\r?\n/);
  // keep the last partial line buffered
  this._buffer = lines.pop();
  for (var l = 0; l < lines.length; l++) {
    var line = lines[l];
    try {
      var obj = JSON.parse(line);
    } catch (er) {
      this.emit('error', er);
      return;
    }
    // push the parsed object out to the readable consumer
    this.push(obj);
  }
  cb();
};

JSONParseStream.prototype._flush = function(cb) {
  // Just handle any leftover
  var rem = this._buffer.trim();
  if (rem) {
    try {
      var obj = JSON.parse(rem);
    } catch (er) {
      this.emit('error', er);
      return;
    }
    // push the parsed object out to the readable consumer
    this.push(obj);
  }
  cb();
};

ステートオブジェクトは、デバッグで役に立つストリームの状態を 情報として持ちます。それを見ることは安全ですが、しかしコンストラクタで設定した オプションフラグを変更することは安全では ありません

Crypto#

Stability: 2 - Unstable; 将来のバージョンにおいて API の変更が
議論されています。互換性を損なう変更は最小限になる予定です。
後述します。

このモジュールにアクセスするには require('crypto') を使用します。

暗号化モジュールは安全な HTTPS ネットワークや http コネクションの一部として使われる、 安全な認証情報をカプセル化する方法を提供します。

同時に OpenSSL のハッシュ、HMAC、暗号、復号、署名、そして検証へのラッパーを一式提供します。

crypto.setEngine(engine, [flags])#

一部または全ての OpenSSL 関数のために、エンジンをロードまたは設定します (フラグによって選択されます)。

engine は id か、エンジンの共有ライブラリへのパスかのいずれかです。

flags はオプションで、デフォルトは ENGINE_METHOD_ALL です。 以下のフラグから一つまたは組み合わせを指定することが出来ます (constants モジュールに定義されています)。

  • ENGINE_METHOD_RSA
  • ENGINE_METHOD_DSA
  • ENGINE_METHOD_DH
  • ENGINE_METHOD_RAND
  • ENGINE_METHOD_ECDH
  • ENGINE_METHOD_ECDSA
  • ENGINE_METHOD_CIPHERS
  • ENGINE_METHOD_DIGESTS
  • ENGINE_METHOD_STORE
  • ENGINE_METHOD_PKEY_METH
  • ENGINE_METHOD_PKEY_ASN1_METH
  • ENGINE_METHOD_ALL
  • ENGINE_METHOD_NONE

crypto.getCiphers()#

サポートされている暗号の名前からなる配列を返します。

例:

var ciphers = crypto.getCiphers();
console.log(ciphers); // ['AES-128-CBC', 'AES-128-CBC-HMAC-SHA1', ...]

crypto.getHashes()#

サポートされているハッシュアルゴリズムの名前からなる配列を返します。

var hashes = crypto.getHashes();
console.log(hashes); // ['sha', 'sha1', 'sha1WithRSAEncryption', ...]

crypto.createCredentials(details)#

認証情報オブジェクトを作成します。オプションの details は以下のキーを持つ辞書です:

  • pfx : PFX または PKCS12 でエンコードされた秘密鍵、証明書、および CA の 証明書を含む文字列またはバッファ。
  • key : PEM でエンコードされた秘密鍵を保持する文字列。
  • passphrase: 秘密鍵または pfx のパスフレーズ。
  • cert : PEM でエンコードされた証明書を保持する文字列。
  • ca : 信頼できる認証局の証明書が PEM でエンコードされた文字列または 文字列の配列。
  • crl : PEM でエンコードされた CRL (Certificate Revocation List、 失効した証明書の一覧) の文字列または文字列の配列。
  • ciphers: 使用または除外する暗号を記述した文字列。 詳細は http://www.openssl.org/docs/apps/ciphers.html#CIPHER_LIST_FORMAT を参照してください。

'ca' の詳細が与えられなかった場合、node.js はデフォルトとして

http://mxr.mozilla.org/mozilla/source/security/nss/lib/ckfw/builtins/certdata.txt で与えられる、信頼できる認証局の公開されたリストを使用します。

crypto.createHash(algorithm)#

ハッシュオブジェクトを生成して返します。 与えられたアルゴリズムによる暗号ハッシュ関数はダイジェストの生成に使われます。

algorithm は、プラットフォーム上の OpenSSL のバージョンでサポートされている利用可能なアルゴリズムに依存します。 例えば 'sha1''md5''sha256''sha512'、などです。 最近のリリースでは、openssl list-message-digest-algorithms で利用可能なダイジェストアルゴリズムが表示されます。

例: このプログラムはファイルのsha1ハッシュ値を求めます。

var filename = process.argv[2];
var crypto = require('crypto');
var fs = require('fs');

var shasum = crypto.createHash('sha1');

var s = fs.ReadStream(filename);
s.on('data', function(d) {
  shasum.update(d);
});

s.on('end', function() {
  var d = shasum.digest('hex');
  console.log(d + '  ' + filename);
});

Class: Hash#

データのハッシュダイジェストを作成するためのクラスです。

これは読み込みと書き込みの両方が可能な ストリーム です。 書き込まれたデータはハッシュを計算するために使われます。 一度ストリームの書き込み側が閉じられると、計算されたハッシュダイジェストを 読み出すために read() メソッドを使うことができます。 レガシーな update() および digest() メソッドもサポートされます。

crypto.createHash() から返されます。

hash.update(data, [input_encoding])#

与えられた data でハッシュの内容を更新します。 そのエンコーディングは input_encoding で与えられ、'utf8''ascii'、 または 'binary' を指定することができます。 入力が文字列でエンコーディングが与えられなかった場合、エンコーディングは 'binary' が強制されます。 もし dataBuffer なら、input_encoding は無視されます。

これは新しいデータがストリームに流される際に何度も呼び出されます。

hash.digest([encoding])#

渡された全てのデータがハッシュ化されたダイジェストを計算します。 encoding'hex''binary'、または 'base64' のいずれかです。 エンコーディングが与えられなかった場合はバッファが返されます。

注意: digest() メソッドが呼び出された後で hash オブジェクトを使うことはできません。

crypto.createHmac(algorithm, key)#

与えられたアルゴリズムとキーで HMAC を計算する、HMAC オブジェクトを作成して返します。

これは読み込みと書き込みの両方が可能な ストリーム です。 書き込まれたデータはハッシュを計算するために使われます。 一度ストリームの書き込み側が閉じられると、計算されたハッシュダイジェストを 読み出すために read() メソッドを使うことができます。 レガシーな update() および digest() メソッドもサポートされます。

algorithm は OpenSSL でサポートされているアルゴリズムに依存します - 前述の createHash を参照してください。

Class: Hmac#

hmac を作成するためのクラスです。

crypto.createHamc から返されます。

hmac.update(data)#

与えられた data で HMAC の内容を更新します。 これは新しいデータがストリームに流される際に何度も呼び出されます。

hmac.digest([encoding])#

渡された全てのデータが HMAC 化されたダイジェストを計算します。 encoding'hex''binary'、または 'base64' のいずれかです。 エンコーディングが与えられなかった場合はバッファが返されます。

注意: digest() メソッドが呼び出された後で hmac オブジェクトを使うことはできません。

crypto.createCipher(algorithm, password)#

与えられたアルゴリズムとパスワードを使用する暗号オブジェクトを作成して返します。

algorithm は、OpenSSL に依存します。例えば 'aes192' などです。 最近のリリースでは、openssl list-cipher-algorithms で利用可能な暗号アルゴリズムが表示されます。 password はキーと IV の生成に使用されます。 これは 'binary' でエンコードされた文字列または buffer でなければなりません

これは読み込みと書き込みの両方が可能な ストリーム です。 書き込まれたデータはハッシュを計算するために使われます。 一度ストリームの書き込み側が閉じられると、計算されたハッシュダイジェストを 読み出すために read() メソッドを使うことができます。 レガシーな update() および digest() メソッドもサポートされます。

crypto.createCipheriv(algorithm, key, iv)#

与えられたアルゴリズムとキーおよび IV を使用する暗号オブジェクトを作成して 返します。

algorithmcreateCipher() の引数と同じです。 key はアルゴリズムで使用される生のキーです。 ivinitialization vector です。

keyiv'binary' でエンコードされた文字列または buffers でなければなりません

Class: Cipher#

データを暗号化するためのクラスです。

crypto.createCipher および crypto.createCipheriv から返されます。

暗号化オブジェクトは読み込みと書き込みの両方が可能な ストリーム です。 書き込まれたプレーンテキストデータは、読み込み側に暗号化されたデータを 生成するために使われます。 レガシーな update() および final() メソッドもサポートされます。

cipher.update(data, [input_encoding], [output_encoding])#

data で暗号を更新します。 input_encoding で与えられるエンコーディングは 'utf8''ascii''binary' のいずれかです。 エンコーディングが与えられなかった場合はバッファが期待されます。 もし dataBuffer なら、input_encoding は無視されます。

The output_encoding specifies the output format of the enciphered data, and can be 'binary', 'base64' or 'hex'. If no encoding is provided, then a buffer is returned. -->

output_encoding は暗号化されたデータの出力フォーマットを指定するもので、 'utf8''ascii' または 'binary' のいずれかです。 エンコーディングが与えられなかった場合はバッファが返されます。

暗号化されたコンテンツが返されます。これは新しいデータがストリームに流される際に何度も呼び出されます。

cipher.final([output_encoding])#

暗号化されたコンテンツの残りを返します。 output_encoding は次のいずれかです: 'binary''base64' または 'hex'。 エンコーディングが与えられなかった場合はバッファが返されます。

注意: final() メソッドが呼び出された後で cipher オブジェクトを使うことはできません。

cipher.setAutoPadding(auto_padding=true)#

入力データが自動的にブロックサイズにパディングされることを 抑止することができます。 auto_paddingfalse の場合、入力データ全体の長さは 暗号ブロックサイズの倍数でなければなりません。 でなければ、final() は失敗します。 これは非標準のパディング、たとえば PKCS パディングの代わりに 0x0 を使う場合に便利です。 cipher.final() の前に呼び出す必要があります。

cipher.getAuthTag()#

認証された暗号モード (現在サポートされているもの: GCM) では、 このメソッドは与えられたデータから計算された 認証タグ を表現する Buffer を返します。 final() メソッドを使った暗号化が完了した後に呼び出されるべきです!

crypto.createDecipher(algorithm, password)#

与えられたアルゴリズムとパスワードを使用する復号オブジェクトを作成して返します。 これは前述の createCipher() の鏡写しです。

crypto.createDecipheriv(algorithm, key, iv)#

与えられたアルゴリズムとキー、IV を使用する復号オブジェクトを作成して返します。 これは前述の createCipheriv() の鏡写しです。

Class: Decipher#

復号化のためのクラスです。

crypto.createDecipher および crypto.createDecipheriv から返されます。

復号化オブジェクトは読み込みと書き込みの両方が可能な ストリーム です。 書き込まれた暗号化データは、読み込み側にプレーンテキストデータを 生成するために使われます。 レガシーな update() および final() メソッドもサポートされます。

decipher.update(data, [input_encoding], [output_encoding])#

'binary''base64' または 'hex' のいずれかでエンコードされた復号を data で更新します。 エンコーディングが与えられなかった場合はバッファが期待されます。 もし dataBuffer なら、input_encoding は無視されます。

output_decoding は復号化されたプレーンテキストのフォーマットを指定するもので、 'binary''ascii' あるいは 'utf8' のいずれかです。 エンコーディングが与えられなかった場合はバッファが返されます。

decipher.final([output_encoding])#

復号化されたプレーンテキストの残りを返します。 output_decoding'binary''ascii' あるいは 'utf8' のいずれかです。 エンコーディングが与えられなかった場合はバッファが返されます。

注意: final() メソッドが呼び出された後で decipher オブジェクトを使うことはできません。

decipher.setAutoPadding(auto_padding=true)#

データブロックが非標準のパディングで暗号化されている場合、 decipher.final() によるチェックを無効にすることができます。 入力データの長さが暗号ブロックサイズの倍数の場合のみ動作します。 decipher.update() の前に呼び出す必要があります。

decipher.setAuthTag(buffer)#

認証された暗号モード (現在サポートされているもの: GCM) に対して、 このメソッドは受け取った認証タグを渡すために使われなければなりません。 タグが提供されなかった場合や暗号文が改竄された場合は、 final がスローされ、その暗号文は認証が失敗したために破棄されなければ ならないことが示されます。

crypto.createSign(algorithm)#

与えられたアルゴリズムで署名オブジェクトを作成して返します。 最近のOpenSSLのリリースでは、openssl list-public-key-algorithms で利用可能な署名アルゴリズムの一覧が表示されます。例えば 'RSA-SHA256'。

Class: Sign#

署名を作成するためのクラスです。

crypto.createSign から返されます。

署名オブジェクトは書き込み可能な ストリーム です。 書き込まれたデータは署名を生成するために使われます。 全てのデータが書き込まれると、sign() メソッドはその署名を返します。 レガシーな update() メソッドもサポートされます。

sign.update(data)#

署名オブジェクトをデータで更新します。 これは新しいデータがストリームに流される際に何度も呼び出されます。

sign.sign(private_key, [output_format])#

署名オブジェクトに渡された全ての更新データで署名を計算します。

private_key はオブジェクトまたは文字列です。 private_key が文字列なら、それはパスフレーズのない鍵とみなされます。

private_key:

  • key : PEM でエンコードされた秘密鍵を保持する文字列
  • passphrase : 秘密鍵のパスフレーズを表す文字列

'binary''hex'、あるいは 'base64' のいずれかを指定した output_format による署名を返します。 エンコーディングが与えられなかった場合はバッファが返されます。

注意: sign() メソッドが呼び出された後で sign オブジェクトを使うことはできません。

crypto.createVerify(algorithm)#

与えられたアルゴリズムで検証オブジェクトを作成して返します。これは前述の署名オブジェクトと鏡写しです。

Class: Verify#

署名を検証するためのクラスです。

crypto.createVerify から返されます。

検証オブジェクトは書き込み可能な ストリーム です。 書き込まれたデータは与えられた署名を検証するために使われます。 全てのデータが書き込まれると、verify() メソッドは与えられた署名が正しければ true を返します。 レガシーな update() メソッドもサポートされます。

verifier.update(data)#

検証オブジェクトをデータで更新します。 これは新しいデータがストリームに流される際に何度も呼び出されます。

verifier.verify(object, signature, [signature_format])#

署名されたデータを objectsignature で検証します。 object は RSA 公開鍵、DSA 公開鍵、X.509証明書のいずれかを PEM でエンコードしたオブジェクトです。 signature は先に計算したデータの署名で、 その signature_format'binary''hex'、または 'base64' のいずれかです。 エンコーディングが与えられなかった場合はバッファが期待されます。

署名されたデータと公開鍵による検証の結果によって true または false を返します。

注意: verify() メソッドを呼び出した後で verifier オブジェクトを使うことはできません。

crypto.createDiffieHellman(prime_length)#

ディフィー・ヘルマン鍵共有オブジェクトを作成し、 与えられた長さの素数を生成します。生成元は 2 です。

crypto.createDiffieHellman(prime, [encoding])#

与えられた素数からディフィー・ヘルマン鍵共有オブジェクトを作成します。 生成元は 2 です。 エンコーディングは 'binary''hex'、または 'base64' のいずれかです。 エンコーディングが与えられなかった場合はバッファが返されます。

Class: DiffieHellman#

ディフィー・ヘルマン鍵共有のためのクラスです。

crypto.creaateDiffieHellman から返されます。

diffieHellman.generateKeys([encoding])#

ディフィー・ヘルマン法で秘密および公開鍵を作成し、 指定の方法でエンコーディングされた公開鍵を返します。 この鍵は相手側に渡されるものです。 エンコーディングは 'binary''hex'、または 'base64' のいずれかです。 エンコーディングが与えられなかった場合はバッファが返されます。

diffieHellman.computeSecret(other_public_key, [input_encoding], [output_encoding])#

other_public_key を相手側の公開鍵として共有の秘密鍵を計算して返します。 与えられた公開鍵は指定の input_encoding を使って解釈され、 秘密鍵は output_encoding で指定された方法でエンコードされます。 エンコーディングは 'binary''hex'、または 'base64' のいずれかです。 入力のエンコーディングが与えられなかった場合はバッファが期待されます。

出力のエンコーディングが与えられなかった場合はバッファが返されます。

diffieHellman.getPrime([encoding])#

ディフィー・ヘルマン法の素数を指定のエンコーディングで返します。 エンコーディングは 'binary''hex'、または 'base64' のいずれかです。 エンコーディングが与えられなかった場合はバッファが返されます。

diffieHellman.getGenerator([encoding])#

ディフィー・ヘルマン法の生成元を指定のエンコーディングで返します。 エンコーディングは 'binary''hex'、または 'base64' のいずれかです。 エンコーディングが与えられなかった場合はバッファが返されます。

diffieHellman.getPublicKey([encoding])#

ディフィー・ヘルマン法による公開鍵を指定のエンコーディングで返します。 エンコーディングは 'binary''hex'、または 'base64' のいずれかです。 エンコーディングが与えられなかった場合はバッファが返されます。

diffieHellman.getPrivateKey([encoding])#

ディフィー・ヘルマン法による秘密鍵を指定のエンコーディングで返します。 エンコーディングは 'binary''hex'、または 'base64' のいずれかです。 エンコーディングが与えられなかった場合はバッファが返されます。

diffieHellman.setPublicKey(public_key, [encoding])#

ディフィー・ヘルマン法による公開鍵を設定します。 鍵のエンコーディングは 'binary''hex'、または 'base64' のいずれかです。 エンコーディングが与えられなかった場合はバッファが期待されます。

diffieHellman.setPrivateKey(private_key, [encoding])#

ディフィー・ヘルマン法による秘密鍵を設定します。 鍵のエンコーディングは 'binary''hex'、または 'base64' のいずれかです。 エンコーディングが与えられなかった場合はバッファが期待されます。

crypto.getDiffieHellman(group_name)#

事前に定義された Diffie-Hellman 鍵交換オブジェクトを作成します。 サポートされるグループは、'modp1', 'modp2', 'modp5' (RFC 2412 で定義される)、 および 'modp14', 'modp15', 'modp16', 'modp17', 'modp18' (RFC 3526 で定義される) です。 返されるオブジェクトは、前述の crypto.createDiffieHellman() によって作成されたオブジェクトのインタフェースを模倣します。 しかし、 (たとえば diffieHellman.setPublicKey() で) 鍵を交換することはできません。 このルーチンを使うことによるアドバンテージは、 事前にグループ係数を生成することも交換する必要もないため、 処理と通信の時間を共に節約できることです。

例 (共有鍵を取得):

var crypto = require('crypto');
var alice = crypto.getDiffieHellman('modp5');
var bob = crypto.getDiffieHellman('modp5');

alice.generateKeys();
bob.generateKeys();

var alice_secret = alice.computeSecret(bob.getPublicKey(), null, 'hex');
var bob_secret = bob.computeSecret(alice.getPublicKey(), null, 'hex');

/* alice_secret and bob_secret should be the same */
console.log(alice_secret == bob_secret);

crypto.pbkdf2(password, salt, iterations, keylen, [digest], callback)#

非同期の PBKDF2 関数です。 選択された HMAC ダイジェスト関数 (デフォルト: SHA1) を適用して、 要求されたパスワード、salt、および繰り返しの数から、 指定された長さの鍵を生成します。 コールバック関数は二つの引数を受け取ります: (err, derivedKey)

例:

crypto.pbkdf2('secret', 'salt', 4096, 512, 'sha256', function(err, key) {
  if (err)
    throw err;
  console.log(key.toString('hex'));  // 'c5e478d...1469e50'
});

crypto.getHashes() からサポートされる ダイジェスト関数の一覧を得ることが出来ます。

crypto.pbkdf2Sync(password, salt, iterations, keylen, [digest])#

同期版の PBKDF2 関数。 生成された鍵を返すか、例外をスローします。

crypto.randomBytes(size, [callback])#

暗号理論的に強い疑似乱数データを生成します。使用法:

// async
crypto.randomBytes(256, function(ex, buf) {
  if (ex) throw ex;
  console.log('Have %d bytes of random data: %s', buf.length, buf);
});

// sync
try {
  var buf = crypto.randomBytes(256);
  console.log('Have %d bytes of random data: %s', buf.length, buf);
} catch (ex) {
  // handle error
  // most likely, entropy sources are drained
}

注意: もし暗号理論的に強いデータを生成するために十分な累積エントロピーが なければ、エラーがスローされるか、エラーと共にコールバックが呼ばれます。 言い換えると、コールバックを渡さずに crypto.randomBytes() を呼び出しても、 全てのエントロピー源が枯渇するまでブロックするわけではありません。

crypto.pseudoRandomBytes(size, [callback])#

暗号理論的では ない、強い疑似乱数データを生成します。 返されるデータは十分に長ければユニークですが、 必ずしも予測不可能ではありません。 この理由のため、この関数の出力を暗号化キーの生成など、予測不可能であることが 重要なところでは決して使用しないでください。

他の使い方は crypto.randomBytes と同じです。

Class: Certificate#

このクラスは「signed public key & challenges (SPKAC)」のために使われます。 この一連の関数の主な用途は、<keygen> 要素の取り扱いです。 http://www.openssl.org/docs/apps/spkac.html

crypto.Certificate を返します。

Certificate.verifySpkac(spkac)#

妥当なSPKAC かどうかを true または false で返します。

Certificate.exportChallenge(spkac)#

与えられた SPKAC からエンコードされた公開鍵を取り出します。

Certificate.exportPublicKey(spkac)#

与えられた SPKAC からエンコードされたチャレンジを取り出します。

crypto.DEFAULT_ENCODING#

関数が使用するエンコーディングのデフォルトは、文字列かバッファの いずれかにすることができます。

新しいプログラムはおそらくバッファを期待することに注意してください。 これは一時的な手段としてのみ使用してください。

Recent API Changes#

Crypto モジュールは、統合されたストリーム API やバイトデータを扱う Buffer オブジェクトよりも先に Node に追加されました。

そのため、このストリーミングなクラスは他の Node のクラスに見られる 典型的なメソッドを持たず、多くのメソッドは引数や戻り値に Buffer ではなくバイナリエンコードされた文字列を使います。

これはあるユースケースにおいては互換性を損ないますが、 全てのケースではありません。

たとえば、Sign クラスをデフォルト引数で使っていて、 その結果を全く調べずに Verify クラスに渡している場合、 それは以前と同じように動くでしょう。 それは、現時点ではバイナリ文字列を受け取ってそのバイナリ文字列を Veriy オブジェクトに渡しますが、将来は Buffer を受け取ってその Buffer を Verify オブジェクトに渡すようになります。

しかしながら、Buffer が文字列と正確に同じようには動かない何かをしている場合 (例えば、それらを連結したり、データベースに保存したりするなど)、 あるいはバイナリ文字列を Crypto の関数にエンコーディング引数無しで 渡している場合、エンコーディング引数を与えてどのエンコーディングを 使用しているかを指定する必要があります。 以前のようにデフォルトでバイナリ文字列を使うように切り替えるには、 crypto.DEFAULT_ENCODING フィールドに binary を設定します。 新しいプログラムはおそらくバッファを期待することに注意してください。 これは一時的な手段としてのみ使用してください。

TLS (SSL)#

Stability: 3 - Stable

require('tls') でこのモジュールにアクセスします。

tls モジュールは OpenSSL を使用することで Transport Layer Security および Secure Socket Layer: 暗号化されたストリーム通信を提供します。

TLS/SSL は公開/秘密鍵を基礎とします。 どのクライアントとサーバも秘密鍵が必要です。 秘密鍵は次のように作成します

openssl genrsa -out ryans-key.pem 1024

全てのサーバと一部のクライアントは証明書を必要とします。 証明書は認証局の公開鍵または自身によって署名されます。 証明書を作成する最初のステップは「証明書署名要求 (CSR)」ファイルです。 次のようにします:

openssl req -new -key ryans-key.pem -out ryans-csr.pem

CSR から自己署名証明書を作成するには次のようにします:

openssl x509 -req -in ryans-csr.pem -signkey ryans-key.pem -out ryans-cert.pem

他に CSR を認証局に送って署名してもらうこともできます。

(TODO: CA を作るドキュメント、現在は興味あるユーザは Node のソースコードから test/fixtures/keys/Makefile を見る必要がある)

.pfx または .p12 を作成するには次のようにします:

openssl pkcs12 -export -in agent5-cert.pem -inkey agent5-key.pem \
    -certfile ca-cert.pem -out agent5.pfx
  • in: certificate
  • inkey: private key
  • certfile: all CA certs concatenated in one file like cat ca1-cert.pem ca2-cert.pem > ca-cert.pem

Client-initiated renegotiation attack mitigation#

TLS プロトコルでは、クライアントに TLS セッションの再ネゴシエーションを 許します。

残念ながら、セッション再ネゴシエーション要求はサーバサイドに過度なリソースを 要求するため、それは潜在的なサーバ強制停止攻撃となります。

これを軽減するために、再ネゴシエーションは 10 分当たり 3 回までに 制限されています。この制限を超えると、tls.TLSSocket のインスタンス上でエラーが生成されます。この制限は変更可能です:

  • tls.CLIENT_RENEG_LIMIT: 再ネゴシエーションの上限、デフォルトは 3 です。

  • tls.CLIENT_RENEG_WINDOW: 秒単位の再ネゴシエーションウィンドウ、 デフォルトは 10 分です。

あなたが何をしようとしているか十分に理解していない限り、 デフォルトを変更しないでください。

サーバをテストするために、openssl s_client -connect address:port および R<CR> (R キーの後に続けてリターンキー) を 数回繰り返します。

NPN and SNI#

NPN (Next Protocol Negotitation) と SNI (Server Name Indication) は TLS の拡張で、以下を可能にします。

  • NPN - 一つの TLS サーバで複数のプロトコル (HTTP、SPDY) を使用。
  • SNI - 一つの TLS サーバでホスト名の異なる複数の証明書を使用。

Perfect Forward Secrecy#

用語 "Forward Secrecy" あるいは "Perfect Forward Secrecy" とは、 鍵を合意 (すなわち鍵交換) する方法の特徴を説明します。 実際のところ、それは (あなたの) サーバの秘密鍵が漏洩しても、 盗聴者によって解読される通信は、特定の各セッション毎に生成される 鍵のペアを取得したものに限られることを意味します。

これは、ハンドシェークの度にランダムに生成される鍵のペアによって 鍵合意することで達成されます (全てのセッションで同じ鍵を使うのとは対照的です)。 Perfect Forward Secrecy を提供するこの方法の実装は、 「一時的 (ephemeral)」と呼ばれます。

現在の所、Perfect Forward Secrecyとして2つの方法が一般的に使われています (従来の省略形に文字 "E" が負荷されていることに注意してください):

  • DHE - ディフィー・ヘルマン鍵合意プロトコルの「一時的」版です。
  • ECDHE - 楕円曲線ディフィー・ヘルマン鍵合意プロトコルの「一時的」版です。

鍵の生成は高価な処理であるため、「一時的」な方法はパフォーマンスの面で 不利かもしれません。

tls.getCiphers()#

サポートされている SSL 暗号名の配列を返します。

例:

var ciphers = tls.getCiphers();
console.log(ciphers); // ['AES128-SHA', 'AES256-SHA', ...]

tls.createServer(options, [secureConnectionListener])#

新しい tls.Server を作成します。 connectionListenersecureConnection イベントのリスナとして 自動的に登録されます。 options は以下を持つことができます:

  • pfx : PFX または PKCS12 でエンコードされた秘密鍵、証明書、および CA の 証明書を含む文字列またはバッファ (keycert、および ca オプションとは相互に排他的です)。

  • key: PEM フォーマットによるサーバの秘密鍵を持つ文字列または Buffer です (必須)。

  • passphrase: 秘密鍵または pfx のパスフレーズを表す文字列です。

  • cert: PEM フォーマットによる証明書の鍵を持つ文字列または Buffer です (必須)。

  • ca: PEM フォーマットによる信頼できる証明書の文字列または Buffer の配列です。 省略された場合、ベリサインなどのよく知られた「ルート」認証局が使われます。 これらはコネクションの認証に使われます。

  • crl : PEM でエンコードされた CRL (Certificate Revocation List、 失効した証明書の一覧) の文字列または文字列の配列。

  • ciphers: 使用または除外する暗号を記述した文字列です。

    BEAST 攻撃を抑制するために、このオプションと以下に示す honorCipherOrder を共に使って、非 CBC 暗号を優先することを推奨します。

    デフォルトは ECDHE-RSA-AES128-SHA256:AES128-GCM-SHA256:RC4:HIGH:!MD5:!aNULL:!EDH です。 詳細は OpenSSL 暗号リストフォーマットのドキュメント を参照してください。

    ECDHE-RSA-AES128-SHA256AES128-GCM-SHA256 は TLS v1.2 の暗号で、 Node.js が (バンドルされているバージョンなどの) OpenSSL 1.0.1 以降と リンクされている場合に使われます。 honorCipherOrder が有効でない限り、TLS v1.2 を使用していても クライアントはより弱い暗号を要求出来ることに注意してください。

    RC4 は、クライアントがより古いバージョンの TLS プロトコルを喋る場合に フォールバックとして使われます。 RC4 は近年疑いをもたれており、真に繊細なものに対しては 漏洩を考慮すべきです。 国家レベルの何者かがそれを破る力を持っていると推測されています。

    注意: 以前のバージョンのこのセクションは AES256-SHA を 受け入れ可能な暗号であるかのように示していました。 残念ながら、AES256-SHA は CBC 暗号であり、したがって BEAST 攻撃 には弱いです。 使わない でください。

  • ecdhCurve: ECDH 鍵合意で使用する曲線を説明する名前、または全ての ECDH を無効にする false

    デフォルトは prime256v1 です。より詳細は RFC 4492 を参照してください。

  • handshakeTimeout: SSL/TLS ハンドシェークがこの時間 (ミリ秒) 以内に終了しなかった場合は接続をアボートします。 デフォルトは 120 秒です。

    ハンドシェークがタイムアウトすると、tls.Server オブジェクトで 'clientError' イベントが生成されます。

  • honorCipherOrder : 暗号を選択する際に、クライアントではなくサーバの設定を使用します。

    このオプションはデフォルトでは無効ですが、BEAST 攻撃を抑制するために ciphers オプションと共に使用することを 推奨 します。

    注意: SSLv2 が使われる場合は、サーバは設定のリストをクライアントに送信し、 クライアントが暗号を選択します。 SSLv2 のサポートは、node.js が ./configure --with-sslv2 によって 構成されない限り無効です。

  • requestCert: true の場合、サーバは接続しようとするクライアントからの 証明書を要求します。デフォルトは false です。

  • rejectUnauthorized: true の場合、サーバは提供された認証局の リストによって認証されていないコネクションを破棄します. このオプションは requestCerttrue の場合だけ効果があります。 デフォルトは false です。

  • NPNProtocols: NPN プロトコルで使用可能な文字列または Buffer の配列 (プロトコルはその優先度に応じて並んでいる必要があります)。

  • SNICallback(servername, cb): クライアントが TLS 拡張の SNI を サポートしている場合に呼び出される関数です。 二つの引数、servernamecb が渡されます。 SNICallback は、cb(null, ctx) を呼び出す必要があります。 ctx はSecureContext のインスタンスです (SecureContext を取得するために crypto.createCredentials(...).context を使用することができます)。 SNICallback が渡されなかった場合は、デフォルトのコールバックとして 後述する高水準 API が使用されます。

  • sessionTimeout: サーバによって作成された TLS セッション識別子および TLS セッションチケットがタイムアウトするまでの秒数を指定する整数値です。 より詳細は SSL_CTX_set_timeout を参照してください。

  • sessionIdContext: セッション再開のための識別子となる文字列です。 requestCedrttrue の場合、デフォルトはコマンドライン引数から 生成された MD5 ハッシュ値となります。 そうでない場合はデフォルトは提供されません。

  • secureProtocol: 使用する SSL メソッド、たとえば SSLv3_method は SSL version 3 の使用を強制します。可能な値は使用する OpenSSL によって 定義される SSL_METHODS 定数に依存します。

これはシンプルはエコーサーバの例です:

var tls = require('tls');
var fs = require('fs');

var options = {
  key: fs.readFileSync('server-key.pem'),
  cert: fs.readFileSync('server-cert.pem'),

  // This is necessary only if using the client certificate authentication.
  requestCert: true,

  // This is necessary only if the client uses the self-signed certificate.
  ca: [ fs.readFileSync('client-cert.pem') ]
};

var server = tls.createServer(options, function(socket) {
  console.log('server connected',
              socket.authorized ? 'authorized' : 'unauthorized');
  socket.write("welcome!\n");
  socket.setEncoding('utf8');
  socket.pipe(socket);
});
server.listen(8000, function() {
  console.log('server bound');
});

あるいは:

var tls = require('tls');
var fs = require('fs');

var options = {
  pfx: fs.readFileSync('server.pfx'),

  // This is necessary only if using the client certificate authentication.
  requestCert: true,

};

var server = tls.createServer(options, function(socket) {
  console.log('server connected',
              socket.authorized ? 'authorized' : 'unauthorized');
  socket.write("welcome!\n");
  socket.setEncoding('utf8');
  socket.pipe(socket);
});
server.listen(8000, function() {
  console.log('server bound');
});

openssl s_client を使用してこのサーバに接続するテストを行うことができます。

openssl s_client -connect 127.0.0.1:8000

tls.connect(options, [callback])#

tls.connect(port, [host], [options], [callback])#

与えられた porthost (旧 API) または options.portoptions.host で新しいクライアントコネクションを作成します (host が省略された場合、デフォルトは localhost です)。 options は以下を指定したオブジェクトです:

  • host: クライアントが接続するホスト。

  • port: クライアントが接続するポート番号。

  • socket: 新しいソケットを生成するのではなく、与えられたソケット上で セキュアな接続を確立します。 このオプションが指定された場合、host および port は無視されます。

  • pfx : PFX または PKCS12 でエンコードされた秘密鍵、証明書、 およびサーバに対する CA の証明書を含む文字列またはバッファ。

  • key: PEM フォーマットによるサーバの秘密鍵を持つ文字列または Buffer です。

  • passphrase: 秘密鍵または pfx のパスフレーズを表す文字列です。

  • cert: PEM フォーマットによる証明書の鍵を持つ文字列または Buffer です。

  • secureProtocol: The SSL method to use, e.g. SSLv3_method to force SSL version 3. The possible values depend on your installation of OpenSSL and are defined in the constant SSL_METHODS.

  • ca: PEM フォーマットによる信頼できる証明書の文字列または Buffer の配列です。 省略された場合、ベリサインなどのよく知られた「ルート」認証局が使われます。 これらはコネクションの認証に使われます。

  • rejectUnauthorized: true の場合、サーバ証明書は提供された認証局の リストによって検証されます。 認証されなかった場合は 'error' イベントが生成されます; err.code は OpenSSL のエラーコードを含みます。 デフォルトは true です。

  • NPNProtocols: サポートする NPN プロトコルの文字列または Buffer の配列です。 Buffer は次のような形式です: 0x05hello0x5world 最初のバイトは次のプロトコル名の長さです (通常、配列を渡す方がシンプルです: ['hello', 'world'])。

  • servername: TLS 拡張である SNI (Server Name Indication) のサーバ名です。

  • secureProtocol: 使用する SSL メソッド、たとえば SSLv3_method は SSL version 3 の使用を強制します。可能な値は使用する OpenSSL によって 定義される SSL_METHODS 定数に依存します。

callback 引数は 'secureConnect' イベントのリスナとして 加えられます。

tls.connect()tls.TLSSocket オブジェクトを返します。

これは前述のエコーサーバに接続するクライアントの例です:

var tls = require('tls');
var fs = require('fs');

var options = {
  // These are necessary only if using the client certificate authentication
  key: fs.readFileSync('client-key.pem'),
  cert: fs.readFileSync('client-cert.pem'),

  // This is necessary only if the server uses the self-signed certificate
  ca: [ fs.readFileSync('server-cert.pem') ]
};

var socket = tls.connect(8000, options, function() {
  console.log('client connected',
              socket.authorized ? 'authorized' : 'unauthorized');
  process.stdin.pipe(socket);
  process.stdin.resume();
});
socket.setEncoding('utf8');
socket.on('data', function(data) {
  console.log(data);
});
socket.on('end', function() {
  server.close();
});

または:

var tls = require('tls');
var fs = require('fs');

var options = {
  pfx: fs.readFileSync('client.pfx')
};

var socket = tls.connect(8000, options, function() {
  console.log('client connected',
              socket.authorized ? 'authorized' : 'unauthorized');
  process.stdin.pipe(socket);
  process.stdin.resume();
});
socket.setEncoding('utf8');
socket.on('data', function(data) {
  console.log(data);
});
socket.on('end', function() {
  server.close();
});

Class: tls.TLSSocket#

net.Socket のラッパーです。内部的なソケットの read/write 処理を、 入出力データを透過的に暗号化/復号化するように置き換えます。

new tls.TLSSocket(socket, options)#

既存の TCP ソケットから新しい TLSSocket オブジェクトを構築します。

socketnet.Socket のインスタンスです。

options は以下のプロパティを持つことができるオブジェクトです。

  • credentials: crypto.createCredentials( ... ) から得られる オプションの認証情報

  • isServer: もし true なら、TLS ソケットはサーバも土で作成されます

  • server: オプションの net.Server インスタンス

  • requestCert: オプション、tls.createSecurePair を参照

  • rejectUnauthorized: オプション、tls.createSecurePair を参照

  • NPNProtocols: オプション、tls.createServer を参照

  • SNICallback: オプション、tls.createServer を参照

tls.createSecurePair([credentials], [isServer], [requestCert], [rejectUnauthorized])#

Stability: 0 - Deprecated. Use tls.TLSSocket instead.

二つのストリームを持つセキュアペアオブジェクトを作成します。 一つは暗号化されたデータを読み書きし、もう一つは平文のデータを読み書きします。 通常、暗号化されたストリームに外部からの暗号化されたデータが連結され、 暗号化されたストリームの代わりに平文のストリームが使われます。

  • credentials: crypto.createCredentials( ... ) で作成された 証明書オブジェクト。

  • isServer: この TLS コネクションをサーバとしてオープンするかどうかを示す ブーリアン値。

  • requestCert: クライアントからの接続に対して、サーバがクライアントに 証明書を要求するかどうかを示すブーリアン値。 サーバコネクションにのみ適用されます。

  • rejectUnauthorized: クライアント認証が不正だった場合に、 自動的にクライアントを破棄するかどうかを示すブーリアン値。 requestCert が有効なサーバにのみ適用されます。

tls.createSequrePair() は、cleartextencrypted ストリームを プロパティとして持つ SecurePair オブジェクトを返します。

注意: cleartexttls.TLSSocket API と同じです。

Class: SecurePair#

tls.createSecurePair から返されます。

Event: 'secure'#

SecurePair オブジェクトのペアが安全な接続を確立した場合に発生します。

サーバの 'secureConnection' イベントと同様に、 pari.cleartext.authorized によって接続相手の証明書を承認できたかどうかを チェックすることができます。

Class: tls.Server#

このクラスは net.Server のサブクラスで、同じメソッドを持っています。 生の TCP コネクションを受け入れる代わりに、 TLS または SSL を使った暗号化されたコネクションを受け付けます。

Event: 'secureConnection'#

function (tlsSocket) {}

このイベントは、新しい接続のハンドシェークが成功した場合に生成されます。 引数は tls.TLSSocket のインスタンスです。 これはストリームに共通する全てのメソッドとイベントを持っています。

socket.authorized は提供された認証局のいずれかによって 認証されたかを示す boolean 値です。 socket.authorized が false の場合、socket.authorizationError には どのように認証が失敗したのかが設定されます。 暗黙的ですが言及する価値のあること: TLS サーバの設定に依存しますが、 認証されていないコネクションも受け入れられることがあります。 socket.npnProtocol は、選択された NPN プロトコルを持つ文字列です。 socket.servername は、SNI でリクエストされたサーバ名を持つ文字列です。

Event: 'clientError'#

function (exception, tlsSocket) { }

セキュアコネクションが確立される前にクライアントコネクションが 'error' イベントを発した場合 - ここに転送されます。

tlsSocket はエラーが発生した tls.TLSSocket です。

Event: 'newSession'#

function (sessionId, sessionData) { }

TLS セッションが作成された場合に生成されます。 セッションを外部ストレージに保存する場合に使えるでしょう。

注意: このイベントリスナの追加は、イベントリスナが追加された後に確立される 接続に対してのみ効果があります。

Event: 'resumeSession'#

function (sessionId, callback) { }

クライアントが以前の TLS セッションを再開を要求した場合に生成されます。 イベントリスナは与えられた sessionId を使用して外部ストレージから セッションを見つけた場合、callback(null, sessionData) を一度呼び出すことが できます。 セッションを再開できない場合 (すなわち、ストレージに存在しない場合)、 callback(null, null) を呼ぶことができます。 callback(err) を呼び出すと接続を終了し、ソケットを破棄します。

NOTE: adding this event listener will have an effect only on connections established after addition of event listener.

server.listen(port, [host], [callback])#

指定の porthost で接続の受け入れを開始します。 host が省略されると、サーバはどんな IPv4 アドレスからのコネクションも受け入れます (INADDR_ANY)。

この関数は非同期です。 最後の引数 callback はサーバがバインドされると呼び出されます。

より詳細は net.Server を参照してください。

server.close()#

サーバが新しい接続を受け入れることを終了します。 この関数は非同期で、サーバが最終的にクローズされるとサーバは 'close' イベントを生成します。

server.address()#

オペレーティングシステムから報告された、サーバにバインドされたアドレスと アドレスファミリ名、ポートを返します。 より詳しくは net.Server.address() を参照してください。

server.addContext(hostname, credentials)#

クライアントが要求してきた SNI ホスト名と hostname (ワイルドカードを使用可能) がマッチした場合のセキュリティコンテキストを追加します。 credentialskeycert、そして ca を含むことができます。

server.maxConnections#

このプロパティを設定すると、サーバの接続数がこれを越えた場合に接続を破棄します。

server.connections#

サーバの並行コネクションの数です。

Class: CryptoStream#

Stability: 0 - Deprecated. Use tls.TLSSocket instead.

これは暗号化されたストリームです。

cryptoStream.bytesWritten#

下層にあるソケットの bytesWritten にアクセスするプロキシで、 TLS のオーバーヘッドを含めて ソケットに書き込まれたトータルのバイト数を 返します。

Class: tls.TLSSocket#

これは暗号化されたデータの透過的な書き込みなど、 TLS ネゴシエーションによって 要求される全てを行う net.Socket のラップされたバージョンです。

このインスタンスは双方向の Stream インタフェースを実装します。 ストリームに共通な全てのメソッドとイベントを持ちます。

Event: 'secureConnect'#

新しいコネクションの TLS/SSL ハンドシェークが成功すると生成されます。 リスナはサーバの証明書が認証されたかどうかに関わらず呼び出されます。 サーバ証明書が指定した認証局に承認されたかチェックするために tlsSocket.authorized を確認するかはユーザ次第です。 tlsSocket.authorized === falseの場合、 tlsSocket.authorizationError からエラーを見つけることができます。 同様に NPN が使われている場合は tlsSocket.npnProtocol から合意されたプロトコルをチェックすることが出来ます。

tlsSocket.encrypted#

静的な論理値で、常に true です。 TLS ソケットを通常のソケットと区別したい場合に使うことが出来ます。

tlsSocket.authorized#

接続相手の証明書が CA の一つによって署名されていれば true、 そうでなければ false です。

tlsSocket.authorizationError#

接続相手の証明書が認証されなかった理由です。 このプロパティは tlsSocket.authorized === false の場合だけ利用可能になります。

tlsSocket.getPeerCertificate()#

接続相手の証明書を表現するオブジェクトを返します。 返されるオブジェクトは証明書のフィールドに対応するプロパティを持ちます。

例:

{ subject: 
   { C: 'UK',
     ST: 'Acknack Ltd',
     L: 'Rhys Jones',
     O: 'node.js',
     OU: 'Test TLS Certificate',
     CN: 'localhost' },
  issuer: 
   { C: 'UK',
     ST: 'Acknack Ltd',
     L: 'Rhys Jones',
     O: 'node.js',
     OU: 'Test TLS Certificate',
     CN: 'localhost' },
  valid_from: 'Nov 11 09:52:22 2009 GMT',
  valid_to: 'Nov  6 09:52:22 2029 GMT',
  fingerprint: '2A:7A:C2:DD:E5:F9:CC:53:72:35:99:7A:02:5A:71:38:52:EC:8A:DF',
  serialNumber: 'B9B0D332A1AA5635' }

接続相手が証明書を提供しなかった場合は、 null または空のオブジェクトを返します。

tlsSocket.getCipher()#

現在の接続における暗号と SSL/TLS プロトコルのバージョンを表現する オブジェクトを返します。

例:

{ name: 'AES256-SHA', version: 'TLSv1/SSLv3' }

詳細は http://www.openssl.org/docs/ssl/ssl.html#DEALING_WITH_CIPHERSSSL_CIPHER_get_name() および SSL_CIPHER_get_version() を 参照してください。

tlsSocket.renegotiate(options, callback)#

TLSの再ネゴシエーションを開始します。 optionsは以下のフィールドを含むことが出来ます: rejectUnauthorizedrequestCert (詳細は tls.createServer 参照)。 callback(err) は再ネゴシエーションが成功で完了すると、errnull で 実行されます。

注意: 相手側の証明書は、セキュアな接続が確立された後で利用可能になります。

更に注意: サーバとして実行される場合、handshakeTimeout 時間が経過した後、 ソケットはエラーと共に破棄されます。

tlsSocket.setMaxSendFragment(size)#

最大の TLS フラグメントサイズを設定します (デフォルトおよび最大の値は 16384、 最少は 512)。 成功すれば true、そうでなければ false を返します。

小さなフラグメントサイズは、クライアントでのバッファリングの遅延を減少します: 大きなフラグメントは、全てのフラグメントが受信されてその完全性が確かめられるまで TLS 層によってバッファリングされます; 大きなフラグメントは複数のラウンドトリップに分割され、 パケットの喪失や並べ替えにより遅延が発生することがあります。 しかしながら、小さなフラグメントは余分な TLS フレームのバイトと CPU のオーバーヘッドを加えるため、全体としてサーバのスループットを 低下させるでしょう。

tlsSocket.address()#

オペレーティングシステムから報告された、ソケットにバインドされたアドレスと アドレスファミリ名、ポートを返します。 返されるオブジェクトは二つのプロパティを持ちます。例: { port: 12346, family: 'IPv4', address: '127.0.0.1' }

tlsSocket.remoteAddress#

リモートの IP アドレスを表現する文字列です。 例えば、'74.125.127.100' あるいは '2001:4860:a005::68'

tlsSocket.remotePort#

リモートポートの数値表現です。 例えば、443

tlsSocket.localAddress#

文字列表現によるローカル IP アドレスです。

tlsSocket.localPort#

数値表現によるローカルポートです。

StringDecoder#

Stability: 3 - Stable

このモジュールを使用するには require('string_decoder') をします。 StringDecoder はバッファから文字列にデコードします。 これは単純なインターフェース buffer.toString() ですが、 UTF-8 を特別にサポートします。

var StringDecoder = require('string_decoder').StringDecoder;
var decoder = new StringDecoder('utf8');

var cent = new Buffer([0xC2, 0xA2]);
console.log(decoder.write(cent));

var euro = new Buffer([0xE2, 0x82, 0xAC]);
console.log(decoder.write(euro));

Class: StringDecoder#

文字列の引数 encoding を受け取ります。デフォルトは 'utf8' です。

decoder.write(buffer)#

デコードされた文字列を返します。

decoder.end()#

バッファに残った終端のバイト列を返します。

File System#

Stability: 3 - Stable

File I/O は POSIX 標準の関数に対する単純なラッパーとして提供されます。 このモジュールを使用するには require('fs') してください。 全てのメソッドは非同期と同期の形式があります。

非同期の形式は常に最後の引数として完了コールバックを受け取ります。 引数として渡される完了コールバックはメソッドに依存しますが、 最初の引数は常に例外のために予約されています。 操作が成功で完了すると最初の引数は null または undefined となります

同期の形式では、全ての例外はすぐにスローされます。 例外は try/catch で捕まえることも、そのまま通過させることもできます。

非同期バージョンの例です:

var fs = require('fs');

fs.unlink('/tmp/hello', function (err) {
  if (err) throw err;
  console.log('successfully deleted /tmp/hello');
});

同期バージョンです:

var fs = require('fs');

fs.unlinkSync('/tmp/hello')
console.log('successfully deleted /tmp/hello');

非同期メソッドでは順序の保証はありません。 以下のような傾向のエラーがあります。

fs.rename('/tmp/hello', '/tmp/world', function (err) {
  if (err) throw err;
  console.log('renamed complete');
});
fs.stat('/tmp/world', function (err, stats) {
  if (err) throw err;
  console.log('stats: ' + JSON.stringify(stats));
});

fs.statfs.rename より先に実行される可能性がありrます。 正しい方法はコールバックをチェーンすることです。

fs.rename('/tmp/hello', '/tmp/world', function (err) {
  if (err) throw err;
  fs.stat('/tmp/world', function (err, stats) {
    if (err) throw err;
    console.log('stats: ' + JSON.stringify(stats));
  });
});

忙しいプロセスでは、プログラマはこれらの非同期バージョンを使うことが強く推奨されます。 同期バージョンはそれが完了するまでプロセス全体をブロックします - 全ての接続を停止します。

ファイル名には相対パスを使うことが出来ます。しかし、このパスは process.cwd() からの相対パスであることを思い出してください。

fs モジュールのほとんどの関数はコールバック引数を省略することができます。 そうすると、エラーを再スローするコールバックがデフォルトとして使用されます。 本来の呼び出し元のトレースを取得するには、NODE_DEBUG 環境変数を設定してください:

$ cat script.js
function bad() {
  require('fs').readFile('/');
}
bad();

$ env NODE_DEBUG=fs node script.js
fs.js:66
        throw err;
              ^
Error: EISDIR, read
    at rethrow (fs.js:61:21)
    at maybeCallback (fs.js:79:42)
    at Object.fs.readFile (fs.js:153:18)
    at bad (/path/to/script.js:2:17)
    at Object.<anonymous> (/path/to/script.js:5:1)
    <etc.>

fs.rename(oldPath, newPath, callback)#

非同期の rename(2)。完了コールバックには発生し得る例外以外に引数が渡されることはありません。

fs.renameSync(oldPath, newPath)#

同期の rename(2)。

fs.ftruncate(fd, len, callback)#

非同期の ftruncate(2)。完了コールバックには発生し得る例外以外に引数が渡されることはありません。

fs.ftruncateSync(fd, len)#

同期の ftruncate(2)。

fs.truncate(path, len, callback)#

非同期の truncate(2)。 完了コールバックには発生し得る例外以外に引数が渡されることはありません。

fs.truncateSync(path, len)#

同期の truncate(2)。

fs.chown(path, uid, gid, callback)#

非同期の chown(2)。完了コールバックには発生し得る例外以外に引数が渡されることはありません。

fs.chownSync(path, uid, gid)#

同期の chown(2)。

fs.fchown(fd, uid, gid, callback)#

非同期の fchown(2)。完了コールバックには発生し得る例外以外に引数が渡されることはありません。

fs.fchownSync(fd, uid, gid)#

同期の fchown(2)。

fs.lchown(path, uid, gid, callback)#

非同期の lchown(2)。完了コールバックには発生し得る例外以外に引数が渡されることはありません。

fs.lchownSync(path, uid, gid)#

同期の lchown(2)。

fs.chmod(path, mode, callback)#

非同期の chmod(2)。完了コールバックには発生し得る例外以外に引数が渡されることはありません。

fs.chmodSync(path, mode)#

同期の chmod(2)。

fs.fchmod(fd, mode, callback)#

非同期の fchmod(2)。完了コールバックには発生し得る例外以外に引数が渡されることはありません。

fs.fchmodSync(fd, mode)#

同期の fchmod(2)。

fs.lchmod(path, mode, callback)#

非同期の lchmod(2)。完了コールバックには発生し得る例外以外に引数が渡されることはありません。

Mac OS X でのみ利用可能です。

fs.lchmodSync(path, mode)#

同期の lchmod(2)。

fs.stat(path, callback)#

非同期の stat(2)。コールバックは 2 つの引数を受け取る (err, stats)で、 statsfs.Stats オブジェクトです。 詳細は fs.Stats の節を参照してください。

より詳しくは後述の fs.Stats の節を参照してください。

fs.lstat(path, callback)#

非同期の lstat(2)。コールバックは 2 つの引数を受け取る (err, stats)で、 statsfs.Stats オブジェクトです。 lstat() はパスがシンボリックリンクだった場合に、 参照先のファイルではなくそのリンク自身が調べられる点を除いて stat() と同じす。

fs.fstat(fd, callback)#

非同期の fstat(2)。コールバックは 2 つの引数を受け取る (err, stats) で、 statsfs.Stats オブジェクトです。 状態を取得するファイルをファイル記述子 fd で指定することを除いて、 fstat()stat() と同じです。

fs.statSync(path)#

同期の stat(2)。fs.Stats のインスタンスを返します。

fs.lstatSync(path)#

同期の lstat(2)。fs.Stats のインスタンスを返します。

fs.fstatSync(fd)#

同期の fstat(2)。fs.Stats のインスタンスを返します。

fs.link(srcpath, dstpath, callback)#

非同期の link(2)。完了コールバックには発生し得る例外以外に引数が渡されることはありません。

fs.linkSync(srcpath, dstpath)#

同期の link(2)。

fs.symlink(srcpath, dstpath, [type], callback)#

非同期の symlink(2)。 完了コールバックには発生し得る例外以外に引数が渡されることはありません。 type 引数に指定出来るのは 'dir''file'、または 'junction' (デフォルトは 'file') で、これは Windows でのみ有効です (他のプラットフォームでは無視されます)。 Windows のジャンクションポイントは対象に絶対パスを要求することに 注意してください。 'junction' を使うと、destination 引数は自動的に絶対パスに正規化されます。

fs.symlinkSync(srcpath, dstpath, [type])#

同期の symlink(2)。

fs.readlink(path, callback)#

非同期の readlink(2)。コールバックは 2 つの引数を受け取る (err, linkString)です。

fs.readlinkSync(path)#

同期の readlink(2)。シンボリックリンクの持つ文字列値を返します。

fs.realpath(path, [cache], callback)#

非同期の realpath(2)。コールバックは 2 つの引数を受け取る (err, resolvedPath)です。 相対パスを解決するために process.cwd を使用することができます。 cache はオブジェクトで、パスがキーとして含まれていればその値が 強制的に解決されたパスとして扱われ、fs.stat によってパスが実在するかどうかの 確認が省かれます。

例:

var cache = {'/etc':'/private/etc'};
fs.realpath('/etc/passwd', cache, function (err, resolvedPath) {
  if (err) throw err;
  console.log(resolvedPath);
});

fs.realpathSync(path, [cache])#

同期の realpath(2)。解決されたパスを返します。

fs.unlink(path, callback)#

非同期の unlink(2)。完了コールバックには発生し得る例外以外に引数が渡されることはありません。

fs.unlinkSync(path)#

同期の unlink(2)。

fs.rmdir(path, callback)#

非同期の rmdir(2)。完了コールバックには発生し得る例外以外に引数が渡されることはありません。

fs.rmdirSync(path)#

同期の rmdir(2)。

fs.mkdir(path, [mode], callback)#

非同期の mkdir(2)。完了コールバックには発生し得る例外以外に引数が渡されることはありません。 mode のデフォルトは 0777 です。

fs.mkdirSync(path, [mode])#

同期の mkdir(2)。

fs.readdir(path, callback)#

非同期の readdir(3)。ディレクトリの内容を読み込みます。 コールバックは 2 つの引数を受け取る (err, files)で、 files'.''..' を除くディレクトリ内のファイル名の配列です。

fs.readdirSync(path)#

同期の readdir(3)。'.''..' を除くディレクトリ内のファイル名の配列を返します。

fs.close(fd, callback)#

非同期の close(2)。完了コールバックには発生し得る例外以外に引数が渡されることはありません。

fs.closeSync(fd)#

同期の close(2)。

fs.open(path, flags, [mode], callback)#

非同期のファイルオープン。open(2) を参照してください。 フラグは以下になります:

  • 'r' - ファイルを読み込み専用でオープンします。 ファイルが存在しない場合は例外が発生します。
  • 'r+' - ファイルを読み書き両用でオープンします。 ファイルが存在しない場合は例外が発生します。
  • 'rs' - ファイルを同期モードで読み込むためにオープンします。 オペレーティングシステムにローカルファイルシステムのキャッシュを バイパスするように指示します。

    これは主に NFS にマウントされたファイルをオープンして、潜在的に古い ローカルキャッシュをスキップするのに役立ちます。 これはI/O パフォーマンスにとても深刻な影響を与えるため、必要でない限りは このフラグを使用しないでください。

    これは fs.open() を同期的なブロッキング呼び出しにするわけではないことに 注意してください。 それが必要な場合は fs.openSync() を使用すべきです。

  • 'rs+' - ファイルを読み書き両方でオープンし、OS に同期的にオープンするように 伝えます。これを使用する際の警告は 'rs' の注意を参照してください。
  • 'w' - ファイルを書き込み専用でオープンします。 ファイルは作成されるか (存在しない場合)、または長さ 0 に切り詰められます (存在する場合)。
  • 'wx' - 'w' と似ていますが、path が存在すると失敗します。
  • 'w+' - ファイルを読み書き両用でオープンします。 ファイルは作成されるか (存在しない場合)、または長さ 0 に切り詰められます (存在する場合)。
  • 'wx+' - 'w+' と似ていますが、path が存在すると失敗します。
  • 'a' - ファイルを追記用でオープンします。 ファイルが存在しない場合は作成されます。
  • 'ax' - 'a' と似ていますが、path が存在すると失敗します。
  • 'a+' - ファイルを読み込みおよび追記用でオープンします。 ファイルが存在しない場合は作成されます。
  • 'ax+' - 'a+' と似ていますが、path が存在すると失敗します。

mode はファイルモード (許可とスティッキービット) を設定しますが、 それはファイルが作成される場合に限られます。 デフォルトは 0666 です。

コールバックは 2 つの引数を受け取る (err, fd)です。

排他フラグ 'x' (open(2) の O_EXCL フラグ) は、 path が新しいファイルとして作成されることを保証します。 POSIX システムでは、path がたとえ存在しないファイルへのシンボリックだとしても 存在すると見なされます。 排他モードはネットワークファイルシステムでは動くかもしれませんし、 動かないかもしれません。

Linux では、ファイルを追記モードでオープンした場合、 ポジションを指定した書き込みは動作しません。 カーネルはポジション引数を無視し、データを常にファイルの最後に追記します。

fs.openSync(path, flags, [mode])#

同期版の open(2)。

fs.utimes(path, atime, mtime, callback)#

fs.utimesSync(path, atime, mtime)#

渡されたパスが参照するファイルのタイムスタンプを変更します。

fs.futimes(fd, atime, mtime, callback)#

fs.futimesSync(fd, atime, mtime)#

渡されたファイル記述子が参照するファイルのタイムスタンプを変更します。

fs.fsync(fd, callback)#

非同期の fsync(2)。完了コールバックには発生し得る例外以外に引数が渡されることはありません。

fs.fsyncSync(fd)#

同期の fsync(2)。

fs.write(fd, buffer, offset, length[, position], callback)#

fd で指定されたファイルに buffer を書き込みます。

offsetlength は書き込まれるバッファの部分を決定します。

position はデータが書き込まれる位置をファイルの先頭からのオフセットで示します。 position が数値型ではない (typeof position !== 'number') 場合、 データは現在の位置から書き込まれます。pwrite(2) を参照してください。

コールバックは 3 つの引数が与えられる (err, written, buffer) で、 writtenbuffer から書き込まれたバイト数を示します。

同じファイルに対してコールバックされるのを待つことなく fs.write() を何度も呼び出すことは、安全ではないことに注意してください。 このシナリオでは、 fs.createWriteStream() を強く推奨します。

Linux では、ファイルを追記モードでオープンした場合、 ポジションを指定した書き込みは動作しません。 カーネルはポジション引数を無視し、データを常にファイルの最後に追記します。

fs.write(fd, data[, position[, encoding]], callback)#

fd で指定されたファイルに data を書き込みます。 もし data が Buffer のインスタンスではない場合、値は強制的に文字列化されます。

position はデータが書き込まれる位置をファイルの先頭からのオフセットで示します。 position が数値型ではない (typeof position !== 'number') 場合、 データは現在の位置から書き込まれます。pwrite(2) を参照してください。

encoding は期待される文字列のエンコーディングです。

コールバックは引数 (err, written, string) を受け取ります。 written は渡された文字列から何 バイト が書き込まれたかを示します。 書き込まれたバイト数は文字列の文字数とは異なることに注意してください。 詳細は Buffer.byteLength を参照してください。

buffer の書き込みとは異なり、文字列全体が書き込まれます。 部分文字列を指定することはできません。 これは、書き込まれることになるデータのバイト単位のオフセットと、 文字列のオフセットは異なるかもしれないためです。

同じファイルに対してコールバックを待つことなく fs.write() を繰り返し呼び出すのは安全ではないことに注意してください。 このシナリオでは、fs.createWriteStream() を強く推奨します。

Linux では、追記モードでオープンしたファイルに対してポジションを指定した 書き込みは動作しません。カーネルはポジション引数を無視し、 常にデータをファイルの最後に追加します。

fs.writeSync(fd, buffer, offset, length[, position])#

fs.writeSync(fd, data[, position[, encoding]])#

同期版の fs.write()。書き込まれたバイト数を返します。

fs.read(fd, buffer, offset, length, position, callback)#

fd で指定されたファイルからデータを読み込みます。

buffer はデータが書き込まれるバッファです。

offset は書き込みを開始するバッファ内のオフセットです。

length は読み込むバイト数を指定する整数です。

position はファイルの読み込みを開始する位置を指定する整数です。 positionnull の場合、データは現在の位置から読み込まれます。

コールバックは3つの引数が与えられる (err, bytesRead, buffer) です。

fs.readSync(fd, buffer, offset, length, position)#

同期版の fs.readbytesRead の数を返します。

fs.readFile(filename, [options], callback)#

  • filename {String}
  • options {Object}
    • encoding {String | Null} デフォルトは null
    • flag {String} デフォルトは 'r'
  • callback {Function}

ファイル全体の内容を非同期に読み込みます。例:

fs.readFile('/etc/passwd', function (err, data) {
  if (err) throw err;
  console.log(data);
});

コールバックは 2 つの引数が渡される (err, data) で、data はファイルの内容です。

エンコーディングが指定されなければ、生のバッファが渡されます。

fs.readFileSync(filename, [options])#

同期版の fs.readFilefilename の内容を返します。

encoding オプションが指定されるとこの関数は文字列を返します。 そうでなければバッファを返します。

fs.writeFile(filename, data, [options], callback)#

  • filename {String}
  • data {String | Buffer}
  • options {Object}
    • encoding {String | Null} デフォルトは 'utf8'
    • mode {Number} デフォルトは 438 (8進数の 0666)
    • flag {String} デフォルトは 'w'
  • callback {Function}

非同期にデータをファイルに書き込みます。 ファイルが既に存在する場合は置き換えられます。 data は文字列またはバッファです。

data がバッファの場合、encoding オプションは無視されます。 デフォルトは 'utf8' です。

例:

fs.writeFile('message.txt', 'Hello Node', function (err) {
  if (err) throw err;
  console.log('It\'s saved!');
});

fs.writeFileSync(filename, data, [options])#

同期版の fs.writeFile

fs.appendFile(filename, data, [options], callback)#

  • filename {String}
  • data {String | Buffer}
  • options {Object}
    • encoding {String | Null} デフォルトは 'utf8'
    • mode {Number} デフォルトは 438 (8進数の 0666)
    • flag {String} デフォルトは 'a'
  • callback {Function}

非同期にデータをファイルに追加します。 ファイルが存在しなければ作成されます。 data は文字列またはバッファです。

例:

fs.appendFile('message.txt', 'data to append', function (err) {
  if (err) throw err;
  console.log('The "data to append" was appended to file!');
});

fs.appendFileSync(filename, data, [options])#

同期版の fs.appendFile

fs.watchFile(filename, [options], listener)#

Stability: 2 - Unstable.  Use fs.watch instead, if possible.

filename の変更を監視します。コールバックの listener はファイルがアクセスされる度に呼び出されます。

第 2 引数はオプションです. options が与えられる場合、それは boolean の persistentinterval の二つのメンバを含むオブジェクトです。 persistent はファイルが監視されている間、 プロセスが実行し続けることを示します。 interval は対象をポーリングする間隔をミリ秒で示します デフォルトは { persistent: true, interval: 5007 } です。

listener は現在の状態オブジェクトと前の状態オブジェクトの 2 つの引数を受け取ります:

fs.watchFile('message.text', function (curr, prev) {
  console.log('the current mtime is: ' + curr.mtime);
  console.log('the previous mtime was: ' + prev.mtime);
});

これらの状態オブジェクトは fs.Stat のインスタンスです。

もしファイルがアクセスされただけでなく、変更された時の通知が必要であれば、curr.mtimeprev.mtime を比較する必要があります。

fs.unwatchFile(filename, [listener])#

Stability: 2 - Unstable.  Use fs.watch instead, if possible.

filename の変更に対する監視を終了します。 listener が指定された場合は該当の listener だけが取り除かれます。 そうでなければ、全ての リスナが取り除かれ、 filenam の監視は事実上終了します。

監視されていないファイル名を指定した fs.unwatchFile() の呼び出しは エラーになるのではなく、何もしません。

fs.watch(filename, [options], [listener])#

Stability: 2 - Unstable.

filename の変更を監視します。 filename はファイルまたはディレクトリのどちらかです。 戻り値のオブジェクトは fs.FSWatcher です。

第 2 引数はオプションです。 もし指定されるなら、options はオブジェクトであるべきです。 サポートされる boolean のメンバは persistentrecursive です。 persistent はファイルが監視されている間、 プロセスが実行し続けることを示します。 recursive は監視対象が全てのサブディレクトリか、 そのディレクトリだけかを示します。 これは、ディレクトリが指定された場合で、サポートされるプラットフォームの場合のみ 適用されます (後述の「Caveats」を参照してください)。 デフォルトは { persistent: true, recursive: false } です。

リスナーコールバックは二つの引数 (event, filename) を与えられます。 event'rename' または 'change'、そして filename はイベントを 引き起こしたファイルの名前です。

Caveats#

fs.watch API はプラットフォーム間で 100% 完全ではありmせんし、 いくつかのシチュエーションで利用不可能です。

recursive オプションは OS X でのみサポートされます。 FSEventsだけがこのタイプのファイル監視をサポートしているので、 他のプラットフォームがすぐに追加される見込みはありません。

Availability#

この機能は下層のオペレーティングシステムが提供するファイルシステム変更の 通知に依存します。

  • Linux システムでは inotify が使われます。
  • BSD システム では kqueue が使われます。
  • OSX では、ファイルには kqueue、ディレクトリには 'FSEvents' が使われます。
  • SunOS システム (Solaris および SmartOS を含みます) では event ports が使われます。
  • Windows システムでは、この機能は ReadDirectoryChangesW に依存します。

何らかの理由で下層の機能が使えない場合、fs.watch() は使えません。 たとえば、ネットワークファイルシステム (NFS、SMB、その他) はしばしば 信頼できないか全く動作しません。

stat をポーリングする fs.watchFile() を使うことはできますが、 それは遅くて信頼性はより低くなります。

Filename Argument#

コールバックに提供される filename 引数は、 全てのプラットフォームでサポートされるわけではありません (現時点では Linux と Windows でのみサポートされます)。 サポートされるプラットフォームであっても、filename が常に提供されることが 保証されているわけではありません。 そのため、コールバックは filename 引数が常に提供されると仮定せず、 それが null だったときの代替手段を持つべきです。

fs.watch('somedir', function (event, filename) {
  console.log('event is: ' + event);
  if (filename) {
    console.log('filename provided: ' + filename);
  } else {
    console.log('filename not provided');
  }
});

fs.exists(path, callback)#

与えられたパスがファイルシステム上に存在するかどうか検査します。 そして引数の callback を真か偽か検査の結果とともに呼び出します。 例:

fs.exists('/etc/passwd', function (exists) {
  util.debug(exists ? "it's there" : "no passwd!");
});

fs.exists() は時代錯誤で、存在する理由は歴史的経緯だけです。 あなたのコードでこれを使うべき理由があってはいけません。

とりわけ、ファイルをオープンする前に存在をチェックするのは、 あなたのコードを競合条件に対して脆弱にするアンチパターンです: fs.exists()fs.open() の間に別のプロセスがファイルを 削除するかもしれません。 単純にファイルをオープンして、それが存在しない時はエラーを処理してください。

fs.existsSync(path)#

同期版の fs.exists です。

Class: fs.Stats#

fs.stat()fs.lstat()fs.fstat()、そしてそれらの同期版 から返される オブジェクトはこの型です。

  • stats.isFile()
  • stats.isDirectory()
  • stats.isBlockDevice()
  • stats.isCharacterDevice()
  • stats.isSymbolicLink() (fs.lstat() でのみ有効)
  • stats.isFIFO()
  • stats.isSocket()

util.inspect(stats) は通常のファイルに対して次のような文字列を返します。

{ dev: 2114,
  ino: 48064969,
  mode: 33188,
  nlink: 1,
  uid: 85,
  gid: 100,
  rdev: 0,
  size: 527,
  blksize: 4096,
  blocks: 8,
  atime: Mon, 10 Oct 2011 23:24:11 GMT,
  mtime: Mon, 10 Oct 2011 23:24:11 GMT,
  ctime: Mon, 10 Oct 2011 23:24:11 GMT,
  birthtime: Mon, 10 Oct 2011 23:24:11 GMT }

atimemtimebirthtime、そして ctimeDate オブジェクトであり、その値を比較するには適切な方法があるということに 注意してください。もっとも一般的に使われる getTime()1970年 1月 1日 からの経過時間をミリ秒単位で返します。 それは比較には十分ですが、曖昧な情報を表示するには別の方法があります。 より詳しい情報は MDN JavaScript Reference で探すことができます。

Stat Time Values#

stat オブジェクト中の時間は以下の意味を持ちます。

  • atime "Access Time" - ファイルが最後にアクセスされた時間。 mknod(2)utimes(2)、そして read(2)` システムコールによって変更されます。
  • mtime "Modified TIme" - ファイルが最後に変更された時間。 mknod(2)utimes(2)、そして write(2)` システムコールによって変更されます。
  • ctime "Change Time" - ファイルの属性 (iノードのデータ) が最後に変更された 時間 chmod(2)chown(2)link(2)mknod(2)rename(2)unlink(2)utimes(2)read(2)、そしてwrite(2)システムコールによって変更されます。
  • birthtime "Birth Time" - ファイルが作成された時間。 birthtime を利用できないファイルシステムでは、このフィールドは citme と同じか、1970-01-01T00:00Z (Unix エポック時刻の 0) を持ちます。 Darwin およびその他の FreeBSD 方言は、utimes(2) システムコールによって 現在の birthtime より前の時間を atime に明示的に設定した場合も 変更されます。

Node v0.12 より前、Windows システムでは ctimebirthtime を保持していました。v0.12 では、Unix システムでは決してそうではなかったように ctime は "creation time" ではないことに注意してください。

fs.createReadStream(path, [options])#

新しい ReadStream オブジェクトを返します (Readable Stream を参照してください)。

options は以下のデフォルト値を持つオブジェクトです:

{ flags: 'r',
  encoding: null,
  fd: null,
  mode: 0666,
  autoClose: true
}

ファイル全体を読み込む代わりに一部の範囲を読み込むため、 optionsstart および end を含めることができます。 startend はどちらも包含的で0から始まります。 encoding'utf8''ascii'、または 'base64' です。

autoClosefalse の場合、エラーが発生しない限りファイル記述子は クローズされません。ファイルをクローズし、ファイル記述子が リークしないようにするのはあなたの責務です。 autoClosetrue に設定されると (デフォルトの振る舞いです)、 error または end によってファイル記述子は自動的にクローズされます。

100 バイトの長さを持つファイルの最後の 10 バイトを読み込む例:

fs.createReadStream('sample.txt', {start: 90, end: 99});

Class: fs.ReadStream#

ReadStreamReadable Stream です。

Event: 'open'#

  • fd {Integer} ReadStream で使われる ファイル記述子。

ReadStream のファイルがオープンされた場合に生成されます。

fs.createWriteStream(path, [options])#

新しい WriteStream オブジェクトを返します (Writable Stream を参照してください)。

options は以下のデフォルト値を持つオブジェクトです:

{ flags: 'w',
  encoding: null,
  mode: 0666 }

options にはデータをファイルのどの位置に書き込むかを指定する start を含めることができます。 ファイルを置換するのではなく変更する場合は、 flags にデフォルトの w ではなく r+ が必要となります。

Class: fs.WriteStream#

WriteStreamWritable Stream です。

Event: 'open'#

  • fd {Integer} WriteStream で使われる ファイル記述子。

WriteStream のファイルがオープンされた場合に生成されます。

file.bytesWritten#

これまでに書き込まれたバイト数。 書き込みがキューイングされたままのデータは含まれません。

Class: fs.FSWatcher#

fs.watch() が返すオブジェクトはこの型です。

watcher.close()#

fs.FSWatcher に与えられたファイルの監視を終了します。

Event: 'change'#

  • event {String} ファイルシステム変更の種類です。
  • filename {String} 変更されたファイル名です (もし利用可能であれば)。

監視しているファイルまたはディレクトリに変更があると生成されます。 詳しくは fs.watch を参照してください。

Event: 'error'#

  • error Error object

エラーが発生すると生成されます。

Path#

Stability: 3 - Stable

このモジュールはファイルのパスに対する処理や変換を行うユーティリティを含みます。 ほとんどのメソッドは文字列の変換だけを行います。 パスが正しいか検証するためにファイルシステムに尋ねることはありません。

このモジュールを利用するにはrequire('path')を呼び出してください。 このモジュールは以下のメソッドを提供します。

path.normalize(p)#

複数のスラッシュが見つかると、それらは一つに置換されます; パスの最後にスラッシュが含まれていると、それは維持されます。 Windows ではバックスラッシュが使われます。

例:

path.normalize('/foo/bar//baz/asdf/quux/..')
// returns
'/foo/bar/baz/asdf'

path.join([path1], [path2], [...])#

全ての引数を一つに結合し、結果として得られるパスを正規化します。

引数は文字列でなくてはなりません。 v0.8 では、非文字列の引数は静かに無視されていました。 v0.10 以降では、例外がスローされます。

例:

path.join('/foo', 'bar', 'baz/asdf', 'quux', '..')
// returns
'/foo/bar/baz/asdf'

path.join('foo', {}, 'bar')
// throws exception
TypeError: Arguments to path.join must be strings

path.resolve([from ...], to)#

to の絶対パスを解決します。

もし to が既に絶対パスでなければ、絶対パスが見つかるまで from 引数を右から左の順で先頭に加えます。 全ての from を加えた後、パスがまだ絶対パスでなければ、カレントワーキングディレクトリが同様に使われます。 結果のパスは正規化され、解決されたパスがルートディレクトリでない限り末尾のスラッシュは削除されます。 文字列でない引数は無視されます。

それはシェルにおける cd コマンドの列だと考えることができます。

例:

path.resolve('foo/bar', '/tmp/file/', '..', 'a/../subfile')

これは以下と同様です。

cd foo/bar
cd /tmp/file/
cd ..
cd a/../subfile
pwd

いは、それぞれのパスが必ずしも存在する必要がないことと、ファイルでも構わないことです。

例:

path.resolve('/foo/bar', './baz')
// returns
'/foo/bar/baz'

path.resolve('/foo/bar', '/tmp/file/')
// returns
'/tmp/file'

path.resolve('wwwroot', 'static_files/png/', '../gif/image.gif')
// if currently in /home/myself/node, it returns
'/home/myself/node/wwwroot/static_files/gif/image.gif'

path.isAbsolute(path)#

path が絶対パスかどうかを判定します。 絶対パスは現在の作業ディレクトリに関係なく、 常に同じ場所に解決されます。

Posix の例:

path.isAbsolute('/foo/bar') // true
path.isAbsolute('/baz/..')  // true
path.isAbsolute('qux/')     // false
path.isAbsolute('.')        // false

Windows の例:

path.isAbsolute('//server')  // true
path.isAbsolute('C:/foo/..') // true
path.isAbsolute('bar\\baz')   // false
path.isAbsolute('.')         // false

path.relative(from, to)#

from から to への相対パスを解決します。

二つの絶対パスがあり、一方から他方への相対パスを得なければならない場合があります。 これは実際のところ、path.resolve() とは逆の変換です。 それは以下を意味します:

path.resolve(from, path.relative(from, to)) == path.resolve(to)

例:

path.relative('C:\\orandea\\test\\aaa', 'C:\\orandea\\impl\\bbb')
// returns
'..\\..\\impl\\bbb'

path.relative('/data/orandea/test/aaa', '/data/orandea/impl/bbb')
// returns
'../../impl/bbb'

path.dirname(p)#

パスに含まれるディレクトリ名を返します。Unixの dirname コマンドと同様です。

例:

path.dirname('/foo/bar/baz/asdf/quux')
// returns
'/foo/bar/baz/asdf'

path.basename(p, [ext])#

パスの最後の要素を返します。Unixの basename コマンドと同様です。

例:

path.basename('/foo/bar/baz/asdf/quux.html')
// returns
'quux.html'

path.basename('/foo/bar/baz/asdf/quux.html', '.html')
// returns
'quux'

path.extname(p)#

パスの最後の要素について、最後の '.' から文字列の最後までのパスの拡張子を返します。 最後の要素に '.' が含まれていなかった場合、もしくは '.' が最初の文字だった場合は、空の文字列を返します。 例:

path.extname('index.html')
// returns
'.html'

path.extname('index.')
// returns
'.'

path.extname('index')
// returns
''

path.sep#

プラットフォーム固有のファイルセパレータ。 '\\' または '/'

*nix での例:

'foo/bar/baz'.split(path.sep)
// returns
['foo', 'bar', 'baz']

Windows での例:

'foo\\bar\\baz'.split(path.sep)
// returns
['foo', 'bar', 'baz']

path.delimiter#

プラットフォーム固有のパス区切り文字、';' または ':'

*nix での例:

console.log(process.env.PATH)
// '/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin'

process.env.PATH.split(path.delimiter)
// returns
['/usr/bin', '/bin', '/usr/sbin', '/sbin', '/usr/local/bin']

Windows での例:

console.log(process.env.PATH)
// 'C:\Windows\system32;C:\Windows;C:\Program Files\nodejs\'

process.env.PATH.split(path.delimiter)
// returns
['C:\Windows\system32', 'C:\Windows', 'C:\Program Files\nodejs\']

net#

Stability: 3 - Stable

net モジュールは非同期なネットワークのラッパーを提供します。 それはサーバとクライアントの両方 (ストリームと呼ばれます) を作成するための方法を含みます。 このモジュールはrequire("net");によって取り込むことができます。

net.createServer([options], [connectionListener])#

新しい TCP サーバを作成します。 connectionListener 引数は 'connection' イベントに対するリスナーとして自動的に加えられます。

options は以下のデフォルト値を持つオブジェクトです:

{ allowHalfOpen: false
}

allowHalfOpentrue だと、反対側のソケットが FIN パケットを送信してきても自動的に FIN を送信しなくなります。 ソケットは読み込み可能ではなくなりますが、書き込み可能のままです。 明示的に end() を呼び出す必要があります。 'end' イベントにより多くの情報があります。

8124 番のポートへの接続を待ち受けるエコーサーバの例:

var net = require('net');
var server = net.createServer(function(c) { //'connection' listener
  console.log('server connected');
  c.on('end', function() {
    console.log('server disconnected');
  });
  c.write('hello\r\n');
  c.pipe(c);
});
server.listen(8124, function() { //'listening' listener
  console.log('server bound');
});

telnet を使ってテストします:

telnet localhost 8124

'/tmp/echo.sock' へのソケットを待ち受けるには、最後から三行目をこのように変更します。

server.listen('/tmp/echo.sock', function() { //'listening' listener

nc を使って UNIX ドメインソケットサーバへ接続します:

nc -U /tmp/echo.sock

net.connect(options, [connectionListener])#

net.createConnection(options, [connectionListener])#

新しいソケットオブジェクトを構築し、与えられたロケーションへのソケットを オープンします。 ソケットが確立されると、'connect' イベントが生成されます。

TCP ソケットの場合、options 引数は以下を指定したオブジェクトです。

  • port: クライアントが接続するポート番号です (必須)。

  • host: クライアントが接続するホストです。デフォルトは localhost です。

  • localAddress: ネットワーク接続をバインドするローカルインタフェースです。

  • family : IP スタックのバージョン。デフォルトは 4 です。

ローカルドメインソケットの場合、options 引数は以下を指定したオブジェクトです。

  • path: クライアントが接続するパスです (必須)。

共通のオプション:

  • allowHalfOpen: true の場合、反対側のソケットが FIN パケットを送信してきても自動的に FIN を送信しなくなります。 デフォルトは false です。 'end' イベントにより多くの情報があります。

connectListener 引数は 'connect' イベントのリスナとして追加されます。

前述のエコーサーバに接続するクライアントの例:

var net = require('net');
var client = net.connect({port: 8124},
    function() { //'connect' listener
  console.log('client connected');
  client.write('world!\r\n');
});
client.on('data', function(data) {
  console.log(data.toString());
  client.end();
});
client.on('end', function() {
  console.log('client disconnected');
});

'/tmp/echo.sock' へのソケットに接続するには、2 行目をこのように変更します。

var client = net.connect({path: '/tmp/echo.sock'});

net.connect(port, [host], [connectListener])#

net.createConnection(port, [host], [connectListener])#

host 上の port に対する TCP コネクションを作成します。 host が省略されると localhost が仮定されます。 connectListener 引数は 'connect' イベントのリスナとして追加されます。

net.connect(path, [connectListener])#

net.createConnection(path, [connectListener])#

path に対する UNIX ドメインソケットを作成します。 connectListener 引数は 'connect' イベントのリスナとして追加されます。

Class: net.Server#

このクラスは TCP またはローカルのサーバを作成するために使われます。

server.listen(port, [host], [backlog], [callback])#

指定された porthost でコネクションの受け入れを開始します。 host が省略されると、サーバはどんな IPv4 アドレスへの接続も受け入れます (INADDR_ANY)。 ポート番号に 0 を指定すると、ランダムなポートが割り当てられます。

バックログは保留された接続のキューの最大長です。 実際の長さは Linux では tcp_max_syn_backlogsomaxconn など、 sysctl の設定を通じて OS によって決定されます。 このパラメータのデフォルト値は 511 (512 ではありません) です。

この関数は非同期です。 サーバがバインドされると、'listening' イベントが生成されます。 最後の引数 callback'listening' のリスナとして加えられます。

一部のユーザが陥る問題の一つは、EADDRINUSE エラーです。 これは、他のサーバが要求されたポートを使っていることを意味します。 これに対照する方法の一つは、1秒待機してからリトライすることです。 これは次のようになります

server.on('error', function (e) {
  if (e.code == 'EADDRINUSE') {
    console.log('Address in use, retrying...');
    setTimeout(function () {
      server.close();
      server.listen(PORT, HOST);
    }, 1000);
  }
});

注意: Node の全てのソケットは SO_REUSEADDR が設定されます)

server.listen(path, [callback])#

  • path String
  • callback Function

与えられた path へのコネクションを待ち受けるするローカルドメインソケットの サーバを開始します。

この関数は非同期です。 サーバがバインドされると、'listening' イベントが生成されます。 最後の引数 callback'listening' のリスナとして加えられます。

UNIX では、ローカルドメインは通常 UNIX ドメインとして知られています。 パスはファイルシステムのパス名です。 それはファイルが作成されるのと同様に命名規則と認可のチェックが行われ、 ファイルシステム上で見ることが出来て、アンリンクされるまで持続されます。

Windows では、ローカルドメインは名前付きパイプを使って実装されます。 パスは \\?\pipe\ または \\.\pipe\ のエントリを参照しなければ なりません。 どんな文字も許されていますが、後者は .. のシーケンスを解決するなど、 パイプ名を処理する必要があるかも知れません。 見た目と異なり、パイプの名前空間はフラットです。 パイプは 持続的ではなく、最後の参照がクローズされると削除されます。 JavaScript の文字列では、パスを指定するためにバックスラッシュを重ねて エスケープする必要があることを忘れないでください。

net.createServer().listen(
    path.join('\\\\?\\pipe', process.cwd(), 'myctl'))

server.listen(handle, [callback])#

  • handle Object
  • callback Function

handle オブジェクトには、サーバまたはソケット (下層の _handle メンバなら なんでも) または、 {fd: <n>} オブジェクトを設定することができます。

これによりサーバは指定したハンドルへの接続を受け付けることになりますが、 ファイル記述子またはハンドルは既にポートまたはドメインソケットに バインドされているものと見なされます。

ファイル記述子へのリスニングは Windows ではサポートされません。

この関数は非同期です。 サーバがバインドされると、'listening' イベントが生成されます。 最後の引数 callback'listening' のリスナとして加えられます。

server.close([callback])#

サーバが新しい接続を受け付けるのを終了しますが、既存の接続は維持します。 この関数は非同期で、サーバは最終的に全ての接続が閉じられると 'close' イベントを生成してクローズされます。 オプションとして、'close' イベントに対するリスナを渡すことができます。

server.address()#

オペレーティングシステムから報告された、サーバにバインドされたアドレスと アドレスファミリ名、ポートを返します。 OSによって割り当てられたアドレスが渡された時に、どのポートに割り当てられたものかを調べるのに便利です。 返されるオブジェクトは 3 つのプロパティを持ちます。例: { port: 12346, family: 'IPv4', address: '127.0.0.1' }

例:

var server = net.createServer(function (socket) {
  socket.end("goodbye\n");
});

// grab a random port.
server.listen(function() {
  address = server.address();
  console.log("opened server on %j", address);
});

'listening' イベントが生成される前に server.address() を呼び出してはいけません。

server.unref()#

イベントシステムにおいて、このサーバだけがアクティブな場合にプログラムを 終了することができるように、unref を呼び出します。 既に unref されたサーバで再び unref が呼び出されても影響はありません。

server.ref()#

unref とは逆に、以前に unref されたサーバが唯一残ったサーバになっても、 プログラムが終了 (デフォルトの動作です) しないように、ref を呼び出します。 既に ref されたサーバで再び ref が呼び出されても影響はありません。

server.maxConnections#

サーバの接続数が大きくなった時に接続を拒否するためにこのプロパティを設定します。

child_process.fork() によって子プロセスに送られたソケットに対して このオプションを使用することは推奨されません。

server.connections#

この関数は 廃止予定 です; 代わりに [server.getConnections()][] を使ってください。

このサーバ上の並行コネクションの数です。

ソケットが child_process.fork() によって子プロセスに送られると、 これは null になります。 fork した子プロセスにポーリングして現在のアクティブな接続を得る代わりに、 非同期の server.getConnections を使用してください。

net.Server は以下のイベントを持つ EventEmitter です:

server.getConnections(callback)#

サーバ上の並行コネクオションの数を非同期に取得します。 ソケットが fork した子プロセスに送られても動作します。

コールバックは errcount の二つの引数を取るべきです。

Event: 'listening'#

server.listen() が呼ばれた後、サーバがバインドされると生成されます。

Event: 'connection'#

  • Socket object The connection object

新しいコネクションが作成されると生成されます。 socketnet.Socket のインスタンスです。

Event: 'close'#

サーバがクローズした時に生成されます。 もし接続が存在すると、このイベントは全ての接続が閉じられるまで 生成されないことに注意してください。

Event: 'error'#

  • Error Object

エラーが発生すると生成されます。 このイベントに続いて 'close' イベントが直接生成される場合があります。 server.listen() の例を参照してください。

Class: net.Socket#

このオブジェクトは TCP またはローカルのソケットを抽象化したものです。 net.Socket のインスタンスは双方向のストリームインタフェースを実装します。 それらはユーザによって (connect() によって) 作成されてクライアントとして使われるか、 Node によって作成されてサーバの 'connection' イベントを通じてユーザに渡されます。

new net.Socket([options])#

新しいソケットオブジェクトを構築します。

options は以下のデフォルト値を持つオブジェクトです。

{ fd: null
  allowHalfOpen: false,
  readable: false,
  writable: false
}

fd に既存のソケットのファイル記述子を指定することができます。 readable および writabletrue を設定すると、 ソケットへの読み込みまたは書き込みが可能になります (注意: fd が渡された場合のみ作用します)。 allowHalfOpen については createServer() および 'end' イベントを参照してください。

socket.connect(port, [host], [connectListener])#

socket.connect(path, [connectListener])#

与えられたソケットでコネクションをオープンします。 porthost が与えられた場合、 ソケットは TCP ソケットとしてオープンされます。 host が省略された場合は localhost が仮定されます。 path が与えられた場合は、 ソケットはそのパスへの UNIX ドメインソケットとしてオープンされます。

通常このメソッドは必要なく、net.createConnection でソケットをオープンします。 これを使うのは、カスタマイズされたソケットを実装している場合だけです。

この関数は非同期です。ソケットが確立されると 'connect' イベントが生成されます。 接続で問題があった場合は 'connect' イベントは生成されず、 例外とともに 'error' イベントが生成されます。

connectListener 引数は 'connect' イベントのリスナに加えられます。

socket.bufferSize#

net.Socket には、socket.write() と常に協調するプロパティがあります。 これはユーザが実行速度を向上させる手助けになります。 コンピュータは、ソケットに書き込まれるデータ量についていくことはできません。 - ネットワーク接続は、単純に遅すぎます。 Node は、ソケットに書き込まれるデータを内部のキューに入れ、可能になった時にワイヤ上に送信します (内部ではソケットのファイル記述子が書き込み可能になるのをポーリングします)。

内部的なバッファリングの結果、メモリ消費が増大するかもしれません。 このプロパティは、現在書き込みのためにバッファリングされている文字数を示します。 (文字数は書き込まれるバイト数とほぼ同じですが、バッファが文字列を含んでいる場合、文字列は遅延的にエンコードされるため、正確なバイト数は分かっていません)

大きな、あるいは増大する bufferSize を体験したユーザは、そのプログラムで pause() および resume() を使ってデータフローを「抑えよう」としなければなりません。

socket.setEncoding([encoding])#

ソケットを入力ストリームとしてエンコーディングを設定します。 詳細は stream.setEncoding() を参照してください。

socket.write(data, [encoding], [callback])#

ソケットにデータを送信します。 文字列の場合、第 2 引数はエンコーディングを指定します - デフォルトは UTF-8 です。

データ全体のカーネルバッファへのフラッシュが成功すると true を返します。 データ全体または一部がユーザメモリ内のキューに入れられた場合は false を返します。 再びバッファが空いた場合は 'drain' イベントが生成されます。

オプションの callback 引数はデータが最終的に出力された時に実行されます - これはすぐには起きないでしょう。

socket.end([data], [encoding])#

ソケットをハーフクローズします。例えば FIN パケットを送信します。 サーバはまだデータを送り続けてくることができます。

data が指定された場合は、 socket.write(data, encoding) に続けて socket.end() を呼び出すのと等価です。

socket.destroy()#

このソケット上でどんな I/O も起こらないことを保証します。 (パースエラーなどの) エラーの場合にだけ必要です。

socket.pause()#

データの読み込みを中断します。つまり、'data' イベントは生成されません。 アップロード速度を落とすために便利です。

socket.resume()#

pause() を呼び出した後で読み込みを再開します。

socket.setTimeout(timeout, [callback])#

このソケットが非アクティブになってから timeout ミリ秒後にタイムアウト するように設定します。デフォルトでは net.Socket はタイムアウトしません。

アイドルタイムアウトが引き起こされると、ソケットは 'timeout' イベントを受信しますが、 コネクションは切断されません。 ユーザは手動で end() または destroy() を呼び出す必要があります。

timeout が 0 の場合、アイドルタイムアウトは無効にされます。

オプションの callback 引数は、timeouot イベントの一回限りのリスナを追加します。

socket.setNoDelay([noDelay])#

Nagle アルゴリズムを無効にします。 デフォルトでは TCP コネクションは Nagle アルゴリズムを使用し、データを送信する前にバッファリングします。 noDelaytrue を設定すると、データは socket.write() を呼び出す度に即座に送信されます。デフォルトは true です。

socket.setKeepAlive([enable], [initialDelay])#

キープアライブ機能を有効/無効にします。 オプションで最初の keepalive probe がアイドルソケットに送信されるまでの初期遅延を設定します。 enable のデフォルトは false です。

initialDelay (ミリ秒) が設定されると、 最後にデータパケットを受信してから最初の keepalive probe までの遅延が設定されます。 初期遅延に 0 が設定されると、デフォルト設定から値を変更されないようにします。 デフォルトは 0 です。

socket.address()#

オペレーティングシステムから報告された、ソケットにバインドされたアドレスと アドレスファミリ名、ポートを返します。 返されるオブジェクトは 3 つのプロパティを持ちます。例: { port: 12346, family: 'IPv4', address: '127.0.0.1' }

socket.unref()#

イベントシステムにおいて、このソケットだけがアクティブな場合にプログラムを 終了することができるように、unref を呼び出します。 既に unref されたソケットで再び unref が呼び出されても影響はありません。

socket.ref()#

unref とは逆に、以前に unref されたソケットが唯一残ったソケットになっても、 プログラムが終了 (デフォルトの動作です) しないように、ref を呼び出します。 既に ref されたソケットで再び ref が呼び出されても影響はありません。

socket.remoteAddress#

リモートの IP アドレスを表現する文字列です。 例えば、'74.125.127.100' あるいは '2001:4860:a005::68'

このメンバはサーバサイドのコネクションにのみ与えられます。

socket.remotePort#

リモートポートの数値表現です。 たとえば、8021

socket.localAddress#

リモートクライアントが接続しているローカル IP アドレスを表現する文字列です。 たとえば、 '0.0.0.0' をリッスンしていて、クライアントが '192.168.1.1' に接続した場合、この値は '192.168.1.1' になります。

socket.localPort#

ローカルポートの数値表現です。 たとえば、8021

socket.bytesRead#

受信したバイトの合計です。

socket.bytesWritten#

送信したバイトの合計です。

net.Socket のインスタンスは以下のイベントを持つ EventEmitter です:

Event: 'lookup'#

ホスト名を解決した後、ただし接続の前に生成されます。 UNIX ソケットには適用されません。

  • err {Error | Null} エラーオブジェクト。 dns.lookup() 参照。
  • address {String} IP アドレス。
  • family {String | Null} アドレスファミリ。 dns.lookup() 参照。

Event: 'connect'#

ソケットコネクションの確立が成功した場合に生成されます。 connect() を参照してください。

Event: 'data'#

  • Buffer object

データを受信した場合に生成されます。 data 引数は Buffer または String です。 データのエンコーディングは socket.setEncoding() で設定されます。 (より詳しい情報は Readable Stream を参照してください)。

Socket'data' イベントを生成した時にリスナが存在しなければ、 データは失われることに注意してください。

Event: 'end'#

ソケットの相手側が FIN パケットを送信した場合に生成されます。

デフォルト (allowHalfOpen == false) では、 保留されていた書き込みキューが出力されるとソケットはファイル識別子を破棄します。 しかし、allowHalfOpen == true が設定されていると、 ユーザがデータを書き込めるようにしておくために、ソケットは自動的に end() を呼び出さないので、 ユーザが end() を呼び出す必要があります。

Event: 'timeout'#

ソケットがタイムアウトして非アクティブになった場合に生成されます。 これはソケットがアイドルになったことを通知するだけです。 利用者は手動でコネクションをクローズする必要があります。

socket.setTimeout() を参照してください。

Event: 'drain'#

書き込みバッファが空になった場合に生成されます。アップロード速度を落とすために使うことができます。

socket.write() の戻り値を参照してください。

Event: 'error'#

  • Error object

エラーが発生した場合に生成されます。'close' イベントはこのイベントの後に直接呼び出されます。

Event: 'close'#

  • had_error {Boolean} ソケットで転送エラーが発生した場合は true です。

ソケットが完全にクローズした場合に生成されます。 引数 had_error は boolean で、ソケットが転送エラーでクローズされたのかどうかを示します。

net.isIP(input)#

input が IP アドレスかテストします。 不正な文字列だと 0、IP バージョン 4 アドレスだと 4,IP バージョン 6 アドレスだと 6 が返されます。

net.isIPv4(input)#

input が バージョン 4 の IP アドレスなら true、そうでなければ false を返します。

net.isIPv6(input)#

input が バージョン 6 の IP アドレスなら true、そうでなければ false を返します。

UDP / Datagram Sockets#

Stability: 3 - Stable

データグラムソケットは require('dgram') で利用可能になります。

重要な注意: dgram.Socket#bind() の振る舞いは v0.10 で変更され、 それは常に非同期になりました。 もし次のようなコードがあると:

var s = dgram.createSocket('udp4');
s.bind(1234);
s.addMembership('224.0.0.114');

これは次のように変更されなければなりません。

var s = dgram.createSocket('udp4');
s.bind(1234, function() {
  s.addMembership('224.0.0.114');
});

dgram.createSocket(type, [callback])#

  • type String. 'udp4' または 'udp6' のいずれか
  • callback Function. 'message' イベントのリスナとして割り当てられる、 Optional
  • Returns: Socket object

指定された種類のデータグラムソケットを作成します。 妥当な種類は udp4udp6です。

オプションのコールバックは message イベントのリスナーとして加えられます。

データグラムを受信したい場合は socket.bind() を呼び出します。 socket.bind() は「全てのインタフェース」のアドレスにランダムなポート (udp4udp6 ソケットの両方で正しいものです) をバインドします。 そのアドレスとポートは socket.address().address および socket.address().port で取得することができます。

Class: dgram.Socket#

dgram Scoket クラスはデータグラム機能をカプセル化します。 それは dgram.createSocket(type, [callback]) を通じて生成されます。

Event: 'message'#

  • msg Buffer object. メッセージ
  • rinfo Object. リモートアドレスの情報

ソケット上で新しいデータグラムが到着した時に生成されます。 msgBuffer で、rinfo は送信者のアドレス情報を持ったオブジェクトです。

socket.on('message', function(msg, rinfo) {
  console.log('Received %d bytes from %s:%d\n',
              msg.length, rinfo.address, rinfo.port);
});

Event: 'listening'#

ソケットでデータグラムの待ち受けを開始すると生成されます。 これは UDP ソケットが作成されるとすぐに発生します。

Event: 'close'#

close() によってソケットがクローズすると生成されます。 このソケットでは新しい message イベントは生成されなくなります。

Event: 'error'#

  • exception Error object

エラーが発生すると生成されます。

socket.send(buf, offset, length, port, address, [callback])#

  • buf Buffer オブジェクトまたは文字列。送信されるメッセージ
  • offset Integer。メッセージの開始位置となるバッファ内のオフセット
  • length Integer。メッセージのバイト長
  • port 整数。接続先のポート番号。
  • address 文字列。接続先のホスト名または IP アドレス。
  • callback 関数。メッセージが送信されるとコールバックされる。任意。

UDP ソケットに対しては、相手先のポートとアドレスは必ず指定しなければなりません。 address パラメータに文字列を提供すると、それは DNS によって解決されます。

アドレスが省略された場合や空文字列だった場合は、代わりに '0.0.0.0' または '::0' が使われます。ネットワークの構成によっては、これらのデフォルト値は 動作したりしなかったりします; 相手先のアドレスは明示的に指定することが最適です。

ソケットが以前に bind の呼び出しによってバインドされていない場合は、 ランダムなポート番号が「全てのインタフェース」アドレスに対してバインドされます (udp4 ソケットでは 0.0.0.0、udp6 では ::0)。

DNS におけるエラー検出と、buf が再利用可能になったことを安全に知るために、 オプションのコールバックを指定することができます。 DNS ルックアップは送信を少なくとも次のイベントループまで遅らせることに 注意してください。 データグラムの送信が行われたことを確実に知る唯一の手段は、 コールバックを使うことです。

マルチバイト文字を考慮してください。 offset および length は文字の位置ではなく、 バイト位置 に関係します。

localhost の適当なポートに UDP パケットを送信する例;

var dgram = require('dgram');
var message = new Buffer("Some bytes");
var client = dgram.createSocket("udp4");
client.send(message, 0, message.length, 41234, "localhost", function(err) {
  client.close();
});

UDP データグラムのサイズについて

IPv4/v6 データグラムの最大のサイズは MTU (Maximum Transmission Unit) と、 Payload Length フィールドサイズに依存します。

  • Payload Length フィールドサイズは 16bit 長で、これは通常のペイロードが IP ヘッダとデータ含めて 64K オクテットより長くなれないことを意味します (65,507 バイト = 65,535 − 8 バイトの UDP ヘッダ − 20 バイトの IP ヘッダ); これは一般的にループバックインタフェースでは正しいものの、 ほとんどのホストとネットワークにとって長大なデータグラムは 現実的ではありません。

  • MTU はリンク層により大きなサイズを与える技術で、 データグラムもサポートできます。 どんなリンクでも、それらが全体として到着するか断片化されるかに関わらず、 IPv4 は最低 69 オクテット必要で、推奨される IPv4MTU576 です (典型的なダイヤルアップ型アプリケーションの MUT 推奨値)。

    IPv6 では最小の MTU1280 オクテットですが、フラグメントを再構築する バッファサイズは最低 1500 オクテットが必要です。 68 オクテットはとても小さいので、もっとも現代的なリンク層技術では、 最小の MTU1500 です (イーサネットと同じです)。

パケットが通過する各リンクの MTU をあらかじめ知ることは できないこと、(受信側の) MTU より大きなデータグラムを送信しても 通常は動作しないことに注意してください (パケットは送り主に知らされることなく黙って捨てられ、 意図した受信者に到達することはありません)。

socket.bind(port, [address], [callback])#

  • port Integer
  • address String、任意
  • callback 引数のない関数、任意。バインディングが終了した時に コールバックされます。

UDP ソケット用です。port とオプションの address でデータグラムを 待ち受けます。 address が指定されなければ、OS は全てのアドレスからの待ち受けを試みます。 バインディングが完了すると、'listening' イベントが生成され、 (もし指定されていれば) callback が呼び出されます。 'listening' イベントリスナと callback の両方を指定しても有害ではありませんが あまり役には立ちません。

束縛されたデータグラムソケットはデータグラムを受信するために node プロセスの 実行を維持し続けます。

バインディングが失敗すると、'error' イベントが生成されます。 まれなケース (たとえばクローズしたソケットへのバインディング) では、 このメソッドは Error をスローすることがあります。

41234 番ポートを待ち受ける UDP サーバの例:

var dgram = require("dgram");

var server = dgram.createSocket("udp4");

server.on("error", function (err) {
  console.log("server error:\n" + err.stack);
  server.close();
});

server.on("message", function (msg, rinfo) {
  console.log("server got: " + msg + " from " +
    rinfo.address + ":" + rinfo.port);
});

server.on("listening", function () {
  var address = server.address();
  console.log("server listening " +
      address.address + ":" + address.port);
});

server.bind(41234);
// server listening 0.0.0.0:41234

socket.close()#

下層のソケットをクローズし、データの待ち受けを終了します。

socket.address()#

オブジェクトが持っているソケットのアドレス情報を返します。 このオブジェクトは addressport、そして family を持っています。

socket.setBroadcast(flag)#

  • flag Boolean

ソケットのオプション SO_BROADCAST を設定またはクリアします。 このオプションが設定されると、UDP パケットはローカルインタフェースのブロードキャスト用アドレスに送信されます。

socket.setTTL(ttl)#

  • ttl Integer

ソケットオプションの IP_TTL を設定します。 TTL は「生存期間」を表しますが、このコンテキストではパケットが通過を許可される IP のホップ数を指定します。 各ルータまたはゲートウェイはパケットを送出する際 TTL をデクリメントします。 ルータによって TTL がデクリメントされて 0 になるとそれは送出されません。 TTL 値の変更は通常、ネットワークの調査やマルチキャストで使われます。

setTTL() の引数は 1 から 255 のホップ数でです。ほとんどのシステムでデフォルトは 64 です。

socket.setMulticastTTL(ttl)#

  • ttl Integer

IP_MULTICAST_TTL ソケットオプションを設定します。 TTL は「生存期間」を表しますが、この文脈では特にマルチキャストのトラフィックにおいてパケットが通過できるIPホップの数を指定します。 それぞれのルーターまたはゲートウェイは、パケットを転送する際に TTL をデクリメントします。 TTL がルーターによって 0 までデクリメントされると、それは転送されません。 setMulticastTTL() の引数はホップを表す数値で、0 から 255 の間です。 ほとんどのシステムでデフォルトは 1 です。

socket.setMulticastLoopback(flag)#

  • flag Boolean

IP_MULTICAST_LOOP ソケットオプションを設定またはクリアします。 このオプションが設定されると、マルチキャストのパケットはローカルインタフェースでも受信できるようになります。

socket.addMembership(multicastAddress, [multicastInterface])#

  • multicastAddress String
  • multicastInterface String, Optional

IP_ADD_MEMBERSHIP ソケットオプションを設定し、マルチキャストグループに参加することをカーネルに伝えます。

multicastInterface が指定されなかった場合は、全ての妥当なインタフェースをメンバーシップに加えようとします。

socket.dropMembership(multicastAddress, [multicastInterface])#

  • multicastAddress String
  • multicastInterface String, Optional

addMembership の反対です - IP_DROP_MEMBERSHIP ソケットオプションによって、マルチキャストグループから抜けることをカーネルに伝えます。 これはソケットのクローズ時やプロセスの終了時にカーネルによって自動的に呼び出されるため、ほとんどのアプリケーションはこれを呼び出す必要がありません。

multicastInterface が指定されなかった場合は、全ての妥当なインタフェースをメンバーシップから削除しようとします。

socket.unref()#

イベントシステムにおいて、このソケットだけがアクティブな場合にプログラムを 終了することができるように、unref を呼び出します。 既に unref されたソケットで再び unref が呼び出されても影響はありません。

socket.ref()#

unref とは逆に、以前に unref されたソケットが唯一残ったソケットになっても、 プログラムが終了 (デフォルトの動作です) しないように、ref を呼び出します。 既に ref されたソケットで再び ref が呼び出されても影響はありません。

DNS#

Stability: 3 - Stable

このモジュールにアクセスするには require('dns') を使用します。 dns モジュールの全てのメソッドは C-Ares を使用します。 ただし、dns.lookup はスレッドプール上で getaddrinfo(3) を使用します。 C-Ares は getaddrinfo よりずっと速いものの、 他のシステムと連携するにはシステムリゾルバの方が一貫しています。 ユーザが net.connect(80, 'google.com') または http.get({ host: 'google.com' }) を行った時、dns.lookup メソッドが使われます。 多数のルックアップを素早く実行したいユーザは、 C-Ares を呼び出すメソッドを使用すべきです。

これは 'www.google.com' を解決して、返された IP アドレスを逆引きで解決する例です。

var dns = require('dns');

dns.resolve4('www.google.com', function (err, addresses) {
  if (err) throw err;

  console.log('addresses: ' + JSON.stringify(addresses));

  addresses.forEach(function (a) {
    dns.reverse(a, function (err, hostnames) {
      if (err) {
        throw err;
      }

      console.log('reverse for ' + a + ': ' + JSON.stringify(hostnames));
    });
  });
});

dns.lookup(hostname, [family], callback)#

ホスト名 (例 'google.com') を解決して最初に見つかった A (IPv4) または AAAA (IPv6) レコードにします。 family は整数の 4 または 6 を指定することができます。 デフォルトは null で、IP v4 と v6 の両方をアドレスファミリーを意味します。

コールバックは引数 (err, address, family) を持ちます。 address 引数は IP v4 または v6 アドレスを表現する文字列です。 family 引数は整数の 4 または 6 で、address のファミリーを意味します (この値は必ずしも最初に lookup に渡す必要はありません)。

エラー時、errError オブジェクトで、err.code はエラーコードです。 err.code'ENOENT' に設定されるのはホスト名が存在しない場合だけではなく、 ファイル記述子が使えないなどルックアップが失敗した場合もあることに 注意してください。

dns.resolve(hostname, [rrtype], callback)#

ホスト名 (例 'google.com') を解決して rrtype で指定されたレコードタイプの配列にします。 妥当な rrtype'A' (IPV4アドレス)、'AAAA' (IPV6アドレス)、 'MX' (mail exchangeレコード), 'TXT' (テキストレコード)、 'SRV' (SRVレコード)、'PTR' (IP を逆引きでルックアップするために使われる)、 'NS' (ネームサーバレコード)、そして 'CNAME' (別名レコード) です。

妥当な rrtype は:

  • 'A' (IPV4 アドレス、デフォルト)
  • 'AAAA' (IPV6 アドレス)
  • 'MX' (mail exchange レコード)
  • 'TXT' (テキストレコード)
  • 'SRV' (SRV レコード)
  • 'PTR' (IP を逆引きでルックアップするために使われる)
  • 'NS' (ネームサーバレコード)
  • 'CNAME' (別名レコード)
  • 'SOA' (start of authority、権威を持つゾーンの開始レコード)

コールバックは引数 (err, addresses) を持ちます。 addresses の各要素の種類はレコードの種類によって決まり、 対応する後述のルックアップメソッドで記述されます。

エラー時、errError オブジェクトで、 err.errno は後述するエラーコードのいずれかです。

dns.resolve4(hostname, callback)#

dns.resolve() と同じですが、IPv4 アドレス (A レコード) だけを問い合わせます。 addresses は IPv4 アドレスの配列です (例
['74.125.79.104', '74.125.79.105', '74.125.79.106'])

dns.resolve6(hostname, callback)#

IPv6 (AAAA レコード) を問い合わせることを除いて dns.resolve4() と同じです。

dns.resolveMx(hostname, callback)#

dns.resolve() と同じですが、mail exchange (MX レコード) だけを問い合わせます。

addresses は MX レコードの配列で、それぞれは priority と exchange の属性を持ちます (例 [{'priority': 10, 'exchange': 'mx.example.com'},...])。

dns.resolveTxt(hostname, callback)#

dns.resolve() と同じですが、テキスト (TXT レコード) だけを問い合わせます。 addresseshostname で利用可能なテキストレコードの配列です。 (例、['v=spf1 ip4:0.0.0.0 ~all'])

dns.resolveSrv(hostname, callback)#

dns.resolve() と同じですが、サービスレコード (SRV レコード) だけを問い合わせます。 addresseshostname で利用可能な SRV レコードの配列です。 SRV レコードのプロパティは priority、weight、port、そして name です (例 [{'priority': 10, {'weight': 5, 'port': 21223, 'name': 'service.example.com'}, ...])。

dns.resolveSoa(hostname, callback)#

dns.resolve() と同じですが、権威を持つゾーンの開始レコード (SOA レコード) だけを問い合わせます。

address は以下の構造を持つオブジェクトです。

{
  nsname: 'ns.example.com',
  hostmaster: 'root.example.com',
  serial: 2013101809,
  refresh: 10000,
  retry: 2400,
  expire: 604800,
  minttl: 3600
}

dns.resolveNs(hostname, callback)#

dns.resolve() と同じですが、ネームサーバレコード (NS レコード) だけを問い合わせます。 addresshostname で利用可能なネームサーバレコードの配列です (例 ['ns1.example.com', 'ns2.example.com'])。

dns.resolveCname(hostname, callback)#

dns.resolve() と同じですが、別名レコード (CNAME レコード) だけを問い合わせます。 addressdomain で利用可能な別名レコードの配列です hostname (e.g., ['bar.example.com'])。

dns.reverse(ip, callback)#

IP アドレスからホスト名の配列へ逆引きで解決します。

コールバックは引数 (err, hostname) を持ちます。

エラー時、errError オブジェクトで、 err.errno は後述するエラーコードのいずれかです。

dns.getServers()#

現在解決に使用されているサーバの IP アドレスを文字列の配列で返します。

dns.setServers(servers)#

解決に使用されるサーバーの IP アドレスを文字列の配列で与えます。

もしアドレスと共にポートを指定しても、下層のライブラリがサポートしないため それらは取り除かれます。

不正なパラメータを与えると例外をスローします。

Error codes#

どの DNS 問い合わせも以下のエラーコードの一つを返します:

  • dns.NODATA: DNS サーバがデータがないと応答した。
  • dns.FORMERR: DNS サーバが問い合わせフォーマットが不正だと主張した。
  • dns.SERVFAIL: DNS サーバが一般的な失敗を返した。
  • dns.NOTFOUND: ドメイン名が見つからない。
  • dns.NOTIMP: DNS サーバは要求された操作を実装していない。
  • dns.REFUSED: DNS サーバが問い合わせを拒否した。
  • dns.BADQUERY: DNS 問い合わせのフォーマットが不正。
  • dns.BADNAME: ホスト名のフォーマットが不正。
  • dns.BADFAMILY: サポートされないアドレスファミリー。
  • dns.BADRESP: DNS 応答のフォーマットが不正。
  • dns.CONNREFUSED: DNS サーバに接続できない。
  • dns.TIMEOUT: DNS サーバへの接続がタイムアウトした。
  • dns.EOF: エンドオブファイル。
  • dns.FILE: ファイルの読み込みがエラー。
  • dns.NOMEM: メモリ不足。
  • dns.DESTRUCTION: チャネルが壊れている。
  • dns.BADSTR: 文字列のフォーマットが不正。
  • dns.BADFLAGS: 不正なフラグが指定された。
  • dns.NONAME: 与えられたホスト名が数値ではない。
  • dns.BADHINTS: 不正なヒントフラグが指定された。
  • dns.NOTINITIALIZED: c-ares ライブラリが初期化されていない。
  • dns.LOADIPHLPAPI: iphlpapi.dll のローディングでエラー。
  • dns.ADDRGETNETWORKPARAMS: GetNetworkParams 関数が見つからない。
  • dns.CANCELLED: DNS 問い合わせがキャンセルされた。

HTTP#

Stability: 3 - Stable

HTTP サーバおよびクライアントを使用するにはいずれも require('http') が必要です。

Node の HTTP インタフェースは、 伝統的に扱いが難しかったプロトコルの多くの機能をサポートするように設計されています。 とりわけ大きくて、場合によってはチャンク化されたメッセージです。 インタフェースは決してリクエストまたはレスポンス全体をバッファリングしないように気をつけています - 利用者はストリームデータを使うことができます。

HTTP メッセージヘッダはこのようなオブジェクトとして表現されます:

{ 'content-length': '123',
  'content-type': 'text/plain',
  'connection': 'keep-alive',
  'host': 'mysite.com',
  'accept': '*/*' }

キーは小文字化されます。値は変更されません。

考えられる HTTP アプリケーションを完全にサポートするために、 Node の HTTP API はとても低水準です。それはストリームのハンドリングとメッセージの解析だけに対処します。 解析はメッセージをヘッダとボディに分けますが、実際のヘッダとボディは解析しません。

複数の値を取ることができると定義されたヘッダは、, 区切りで連結されます。 ただし、set-cookie および cookie ヘッダは例外で、値の配列で表現されます。 content-length のように単一の値だけを持つヘッダはそれに応じて解析され、 その結果は一つだけの値として表現されます。

受信した生のヘッダは rawHeaders プロパティに保持されます。 それは [key, value, key2, value2, ...] の配列です。 たとえば、前述のメッセージヘッダオブジェクトは、以下のような rawHeaders を持つかもしれません:

[ 'ConTent-Length', '123456',
  'content-LENGTH', '123',
  'content-type', 'text/plain',
  'CONNECTION', 'keep-alive',
  'Host', 'mysite.com',
  'accepT', '*/*' ]

http.METHODS#

  • Array

パーサによってサポートされているHTTPメソッドの配列です。

http.STATUS_CODES#

  • Object

全ての HTTP 標準ステータスコードと短い説明のコレクションです。 たとえば、http.STATUS_CODES[404] === 'Not Found'

http.createServer([requestListener])#

新しい Web サーバオブジェクトを返します。

requestListener は自動的に 'request' イベントに加えられる関数です。

http.createClient([port], [host])#

この関数は deprecated です; 代わりに http.request() を使用してください。 新しい HTTP クライアントを構築します。 porthost は接続するサーバを示します。

Class: http.Server#

これは以下のイベントを持つ EventEmitter です:

Event: 'request'#

function (request, response) { }

リクエストの度に生成されます。 コネクションごとに複数のリクエストがあるかもしれないことに注意してください (Keep Alive なコネクションの場合)。 requesthttp.IncomingMessage のインスタンス、 responsehttp.ServerResponse のインスタンスです。

Event: 'connection'#

function (socket) { }

新しい TCP ストリームが確立した時。 socketnet.Socket 型のオブジェクトです。 通常の利用者がこのイベントにアクセスしたくなることはないでしょう。 とりわけ、ソケットはプロトコルパーサにアタッチされるため、 readable イベントを生成しません。 socketrequest.connection からアクセスすることもできます。

Event: 'close'#

function () { }

サーバがクローズした時に生成されます。

Event: 'checkContinue'#

function (request, response) { }

httpの Expect: 100-continue リクエストを受信する度に生成されます。 このイベントが監視されない場合、サーバは自動的に 100 Continue を応答します。

このイベントを処理する場合、クライアントがリクエストボディを送信し続けるべきなら response.writeContinue() を呼び出す必要があります。 あるいは、クライアントがリクエストボディを送信し続けるべきでないなら、 適切な HTTP レスポンス (例えば 400 Bad Request) を生成します。

このイベントが生成されて処理された場合、requestイベントは生成されないことに注意してください。

Event: 'connect'#

function (request, socket, head) { }

クライアントが HTTP の CONNECT メソッドを要求する度に生成されます。 このイベントが監視されない場合、CONNECT メソッドを要求したクライアントのコネクションはクローズされます。

  • request はリクエストイベントの引数と同様に HTTP リクエストです。
  • socket はサーバとクライアントの間のネットワークソケットです。
  • head はトンネリングストリームの最初のパケットを持つ Buffer のインスタンスです。 空の場合もあります。

このイベントが生成された後、リクエスト元のソケットはもう data イベントリスナーを持ちません。 このソケットでサーバへ送られたデータを扱うためにそれをバインドしなければならないことを意味します。

Event: 'upgrade'#

function (request, socket, head) { }

クライアントが HTTP のアップグレードを要求する度に生成されます。 このイベントが監視されない場合、アップグレードを要求したクライアントのコネクションはクローズされます。

  • request はリクエストイベントの引数と同様に HTTP リクエストです。
  • socket はサーバとクライアントの間のネットワークソケットです。
  • head はアップグレードストリームの最初のパケットを持つ Buffer のインスタンスです。 空の場合もあります。

このイベントが生成された後、リクエスト元のソケットはもう data イベントリスナーを持ちません。 このソケットでサーバへ送られたデータを扱うためにそれをバインドしなければならないことを意味します。

Event: 'clientError'#

function (exception, socket) { }

クライアントコネクションが 'error' イベントを発した場合 - ここに転送されます。

socket はエラーが発生した net.Socket オブジェクトです。

server.listen(port, [hostname], [backlog], [callback])#

指定されたポートとホスト名でコネクションの受け入れを開始します。 ホスト名が省略されると、サーバはどんな IPv4 アドレスへの接続も受け入れます (INADDR_ANY)。

UNIX ドメインソケットを待ち受ける場合、ポートとホスト名ではなくファイル名を提供します。

バックログは保留された接続のキューの最大長です。 実際の長さは Linux では tcp_max_syn_backlogsomaxconn など、 sysctl の設定を通じて OS によって決定されます。 このパラメータのデフォルト値は 511 (512 ではありません) です。

この関数は非同期です。最後の引数の callback'listening' イベントのリスナとして加えられます。 詳細は net.Server.listen(port) を参照してください。

server.listen(path, [callback])#

path で与えられたコネクションを待ち受ける UNIX ドメインソケットのサーバを開始します。

この関数は非同期です。最後の引数の callback'listening' イベントのリスナとして加えられます。 詳細は net.Server.listen(path) を参照してください。

server.listen(handle, [callback])#

  • handle Object
  • callback Function

handle オブジェクトには、サーバまたはソケット (下層の _handle メンバなら なんでも) または、 {fd: <n>} オブジェクトを設定することができます。

これによりサーバは指定したハンドルへの接続を受け付けることになりますが、 ファイル記述子またはハンドルは既にポートまたはドメインソケットに バインドされているものと見なされます。

ファイル記述子へのリスニングは Windows ではサポートされません。

この関数は非同期です。最後の引数の callback'listening' イベントのリスナとして加えられます。 詳細は net.Server.listen() を参照してください。

server.close([callback])#

サーバが新しいコネクションを受け付けるのを終了します。 net.Server.close() を参照してください。

server.maxHeadersCount#

受け付けるヘッダ数の上限で、デフォルトは 1000 です。 0 に設定されると、制限しないことになります。

server.setTimeout(msecs, callback)#

  • msecs Number
  • callback Function

ソケットにタイムアウト値を設定し、サーバオブジェクト上で 'timeout' イベントを生成します。 タイムアウトが発生すると、ソケットが引数として渡されます。

サーバオブジェクトに 'timeout' イベントのリスナが存在すると、 それはタイムアウトしたソケットを引数として呼び出されます。

デフォルトでは、サーバのタイムアウト値は 2 分で、 タイムアウトしたソケットは自動的に破棄されます。 しかしながら、'timeout' イベントのコールバックをサーバに割り当てた場合、 タイムアウトしたソケットのハンドリングはあなたの責務となります。

server.timeout#

  • {Number} デフォルト = 120000 (2 分)

不活性なソケットがタイムアウトしたと推定されるまでのミリ秒を表す数値。

ソケットのタイムアウト処理は接続のセットアップ時に行われるため、 この値の変更は既存の接続ではなく、サーバへの 新しい 接続にだけ 影響することに注意してください。

0 を設定すると、到着する接続に対する自動的なタイムアウトの振る舞いは 無効になります。

Class: http.ServerResponse#

このオブジェクトは HTTP サーバ内部 - ユーザではなく - で作成されます。 'request' リスナーの第 2 引数として渡されます。

レスポンスは Writable Stream インタフェースを実装します。 これは以下のイベントを持つ EventEmitter です:

Event: 'close'#

function () { }

response.end() が呼び出されたりフラッシュされる前に、 下層の接続が切断されたことを示します。

Event: 'finish'#

function () { }

レスポンスが送信されると生成されます。 より詳しくいうと、このイベントはレスポンスヘッダおよびボディの 最後のセグメントがネットワーク上へ転送するためにオペレーティングシステムに 渡されると生成されます。 それはクライアントが何かを受信したことを意味しません。

このイベントの後、レスポンスオブジェクトはどんなイベントも生成しません。

response.writeContinue()#

HTTP/1.1 の 100 Continue メッセージをクライアントに送信し、 リクエストボディを送信してもよいことを示します。 Server'checkContinue' イベントを参照してください。

response.writeHead(statusCode, [statusMessage], [headers])#

レスポンスヘッダを送信します。 ステータスコードは 404 のような 3 桁の数字による HTTP ステータスコードです。 最後の引数 headers は、レスポンスヘッダです。 オプションとして人に読める形式の statusMessage を第 2 引数で与えることができます。

例:

var body = 'hello world';
response.writeHead(200, {
  'Content-Length': body.length,
  'Content-Type': 'text/plain' });

このメソッドはメッセージごとに 1 回だけ呼び出されなくてはならず、 response.end() の前に呼び出されなければなりません。

もしこのメソッドが呼び出される前に response.write() または response.end() が呼ばれると、暗黙的で可変のヘッダが算出されて この関数が呼び出されます。

注意: Content-Length は文字数ではなくバイト数で与えられます。 上の例が動作するのは 'hello world' という文字列が単一バイト文字だけを含むためです。 もしボディがより上位にコード化された文字を含む場合は、 指定したエンコーディングによるバイト数を得るために Buffer.byteLength() を使うべきです。 Node は、Content-Length と実際に送信されたレスポンスボディの長さが等しいかどうかチェックしません。

response.setTimeout(msecs, callback)#

  • msecs Number
  • callback Function

ソケットのタイムアウト値を msec に設定します。 コールバックが与えられると、それはレスポンスオブジェクトの 'timeout' イベントのリスナとして加えられます。

リクエスト、レスポンス、そしてサーバのいずれにも 'timeout' リスナが存在しない場合、タイムアウトしたソケットは破棄されます。 もしリクエスト、レスポンス、サーバのいずれかに 'timeout' イベントを 設定した場合、タイムアウトしたソケットのハンドリングはあなたの責務となります。

response.statusCode#

(response.writeHead() が明示的に呼ばれないために) 暗黙的なヘッダが使われる場合、このプロパティはヘッダがフラッシュされる時に クライアントへ送信されるステータスコードを制御します。

例:

response.statusCode = 404;

レスポンスヘッダがクライアントに送信された後、 このプロパティは送信されたステータスコードを示します。

response.statusMessage#

(response.writeHead() が明示的に呼ばれないために) 暗黙的なヘッダが使われる場合、このプロパティはヘッダがフラッシュされる時に クライアントへ送信されるステータスメッセージを制御します。 もし undefined のままの場合はステータスコードに対応する標準のメッセージが 使われます。

例:

response.statusMessage = 'Not found';

レスポンスヘッダがクライアントに送信された後、 このプロパティは送信されたステータスメッセージを示します。

response.setHeader(name, value)#

暗黙的ヘッダのヘッダ値を設定します。 送信されようとしているレスポンスヘッダにこのヘッダが既に含まれている場合、 その値は置き換えられます。 同じ名前で複数のヘッダを送信したい場合は文字列の配列を使ってください。

例:

response.setHeader("Content-Type", "text/html");

または

response.setHeader("Set-Cookie", ["type=ninja", "language=javascript"]);

response.headersSent#

(読み込み専用の) Boolean。 ヘッダが送信済みなら true、それ以外は false です。

response.sendDate#

true の場合、Date ヘッダが自動的に生成され、レスポンスとして送信されます (headers にすでに与えられていない場合)。 デフォルトは true です。

これを無効にするのはテストでのみにすべきです。 HTTP はレスポンスに Date ヘッダを要求します。

response.getHeader(name)#

すでにキューに入れられているが未送信のヘッダを読み上げます. 名前は大文字小文字を区別しないことに注意してください。 これはヘッダが暗黙的にフラッシュされる前だけ呼び出すことができます。

例:

var contentType = response.getHeader('content-type');

response.removeHeader(name)#

暗黙的に送信するためキューに入れられたヘッダを削除します。

例:

response.removeHeader("Content-Encoding");

response.write(chunk, [encoding])#

このメソッドが呼び出され、response.writeHead() が呼び出されなければ、 暗黙的ヘッダモードに切り替わり、暗黙的ヘッダはフラッシュされます。

これはレスポンスボディのチャンクを送信します。 このメソッドはボディの連続した部分を提供するために複数回呼び出されるかもしれません。

chunk は文字列またはバッファにすることができます。 chunk が文字列の場合、どのエンコードでバイトストリームにするかを第 2 引数で指定します。 デフォルトの encoding'utf8' です。

注意: これは生の HTTP ボディで、 高水準のマルチパートボディエンコーディングで使われるものとは無関係です。

初めて response.write() が呼び出されると、 バッファリングされていたヘッダ情報と最初のボディがクライアントに送信されます。 2 回目に response.write() が呼ばれると、 Node はストリーミングデータを分割して送信しようとしていると仮定します。 すなわち、レスポンスはボディの最初のチャンクまでバッファリングされます。

データ全体のカーネルバッファへのフラッシュが成功すると true を返します。 データ全体または一部がユーザメモリ内のキューに入れられた場合は false を返します。 再びバッファが空いた場合は 'drain' イベントが生成されます。

response.addTrailers(headers)#

このメソッドは HTTP トレーラヘッダ (メッセージの最後に置かれるヘッダ) をレスポンスに追加します。

トレーラはレスポンスがチャンク化されたエンコーディングでのみ生成されます; そうでなければ (例えばリクエストが HTTP/1.0)、黙って破棄されます。

HTTP は、トレーラを生成するならそのヘッダフィールドのリストを値として Trailer ヘッダを送信することを要求していることに注意してください。

response.writeHead(200, { 'Content-Type': 'text/plain',
                          'Trailer': 'Content-MD5' });
response.write(fileData);
response.addTrailers({'Content-MD5': "7895bf4b8828b55ceaf47747b4bca667"});
response.end();

response.end([data], [encoding])#

このメソッドはレスポンスの全てのヘッダとボディを送信したことをサーバに伝えます; サーバはメッセージが終了したと考えるべきです。 この response.end() メソッドは各レスポンスごとに呼び出さなければなりません

data が指定された場合、 response.write(data, encoding) に続けて response.end() を呼び出すのと等価です。

http.request(options, [callback])#

Node は HTTP リクエストを行うために、サーバごとにいくつかのコネクションを 保持します。 この関数はその一つを使って透過的にリクエストを発行できるようにします。

options はオブジェクトまたは文字列です。 もし options が文字列なら、それは url.parse() によって自動的に 解析されます。

オプション:

  • host: リクエストを発行するサーバのドメイン名または IP アドレス。
  • hostname: url.parse() サポート。hostnamehost を上書きします。
  • port: リモートサーバのポート。デフォルトは 80 です。
  • localAddress: ネットワーク接続をバインドするローカルインタフェースです。
  • socketPath: Unix ドメインソケット (host:port または socketPath のどちらか)
  • method: HTTP リクエストのメソッドの文字列。デフォルトは 'GET' です。
  • path: リクエストのパス。デフォルトは '/' です。 必要なら問い合わせ文字列を含めるべきです. 例 '/index.html?page=12' 。リクエストパスが不正な文字を含んでいる場合は、 例外がスローされます。現在はスペースだけが拒否されますが、 それは将来変更されるかもしれません。
  • headers: リクエストヘッダを含むオブジェクト。
  • auth: ベーシック認証すなわち Authorization ヘッダのための 'user:password'
  • agent: Agent の振る舞いを制御します。 エージェントが使われる場合、Connection:keep-alive がデフォルトになります。 可能な値は:
    • undefined (デフォルト): ホストとポートで global Agent を使用します。
    • Agent オブジェクト: 明示的に渡された Agent を使用します。
    • false: Agent によるコネクションプーリングを使用しません。 Connection:close の場合のデフォルトです。
    • keepAlive: {Boolean} 将来、他のリクエストで使用できるように、 ソケットをプールに保持します。デフォルトは false です。
    • keepAliveMsecs: {Integer} HTTP キープアライブが使用された場合、 ソケットの接続を維持するために TCP キープアライブパケットを送信する間隔です。 keepAlivetrue に設定された場合だけ関係があります。

オプションの callback 引数は、'response' イベントの 一回限りのリスナとして加えられます。

http.request()http.ClientRequest クラスのインスタンスを返します。 http.ClientRequest のインスタンスは書き込み可能なストリームです。 もし POST リクエストでファイルのアップロードがしたければ、 http.ClientRequest オブジェクトに出力してください。

例:

var options = {
  hostname: 'www.google.com',
  port: 80,
  path: '/upload',
  method: 'POST'
};

var req = http.request(options, function(res) {
  console.log('STATUS: ' + res.statusCode);
  console.log('HEADERS: ' + JSON.stringify(res.headers));
  res.setEncoding('utf8');
  res.on('data', function (chunk) {
    console.log('BODY: ' + chunk);
  });
});

req.on('error', function(e) {
  console.log('problem with request: ' + e.message);
});

// write data to request body
req.write('data\n');
req.write('data\n');
req.end();

この例で req.end() が呼ばれていることに注意してください。 http.request() では、リクエストが終了したことを示すために、 常に req.end() を呼び出さなければなりません - リクエストのボディに出力するデータがなかったとしても。

リクエスト中に何らかのエラー (DNS 解決、TCP レベルのエラー、HTTP パースエラーなど) が発生すると、戻り値のリクエストオブジェクトで 'error' イベントが生成されます。

いくつかの特別なヘッダに注意が必要です。

  • 'Connection: keep-alive' の送信は、サーバへのコネクションを次のリクエストまで持続することを Node に通知します。

  • 'Content-length' ヘッダの送信は、デフォルトのチャンクエンコーディングを無効にします。

  • 'Expect' ヘッダの送信は、リクエストヘッダを即時に送信します。 通常、'Expect: 100-continue' を送信すると、タイムアウトと continue イベントを待ち受けます。詳細は RFC2616 の 8.2.3 節を参照してください。

  • Authorization ヘッダの送信は、auth オプションによるベーシック認証を 上書きします。

http.get(options, [callback])#

ほとんどのリクエストは本文のない GET リクエストであるため、 Node は便利なメソッドを提供します。 このメソッドと http.request() の間の違いは、メソッドを GET に設定して req.end() を自動的に呼び出すことだけです。

例:

http.get("http://www.google.com/index.html", function(res) {
  console.log("Got response: " + res.statusCode);
}).on('error', function(e) {
  console.log("Got error: " + e.message);
});

Class: http.Agent#

HTTP エージェントは HTTP クライアントリクエストでソケットをプーリング するためのものです。

HTTP エージェントでは、クライアントリクエストはデフォルトで Connection:keep-alive を使います。 ソケットを待ってペンディングになっている HTTP リクエストがなければ、 ソケットはクローズされます。 これは、node のプールは高負荷時に keep-alive のメリットを持ちながら、 keep-alive を使用する HTTP クライアントの開発者が手動でクローズする 必要がないことを意味します。 -->

より積極的に HTTP キープアライブを使用したければ、keepAlive フラグを true に設定してエージェントを生成します (後述する コンストラクタオプション 参照)。 すると、エージェントは未使用の ソケットを後で使うためにプールに維持します。 それらは Node プロセスの実行を維持しないように明示的にマークされます。 しかし、キープアライブなエージェントがもはや使われなくなった場合に 明示的に destroy() を呼び出すのはいいことです。 すると、ソケットはシャットダウンされます。

ソケットは 'close' イベントまたは特別な 'agentRemove' イベントが 生成された時にエージェントのプールから削除されます。 これは、一つの HTTP リクエストを長時間オープンしたままにするために、 プールにソケットがとどまらないことを意図するなら、 以下のようにすることができることを意味します:

http.get(options, function(res) {
  // Do stuff
}).on("socket", function (socket) {
  socket.emit("agentRemove");
});

別の方法として、 agent: false を指定することで、 プーリングを使用しないこともできます:

http.get({
  hostname: 'localhost',
  port: 80,
  path: '/',
  agent: false  // create a new agent just for this one request
}, function (res) {
  // Do stuff with response
})

new Agent([options])#

  • options {Object} エージェントに設定される構成可能なオプションの集合。 以下のフィールドを持つことができます:
    • keepAlive: {Boolean} 将来、他のリクエストで使用できるように、 ソケットをプールに保持します。デフォルトは false です。
    • keepAliveMsecs: {Integer} HTTP キープアライブが使用された場合、 ソケットの接続を維持するために TCP キープアライブパケットを送信する間隔。 keepAlivetrue に設定された場合だけ関係があります。
    • maxSockets {Number} ホスト毎に許されるソケットの最大数。 デフォルトは Infinity
    • maxFreeSockets {Number} フリーな状態でオープンしたままにするソケットの 最大数。デフォルトは 256

http.request によって使われるデフォルトの http.globalAgent は、 これら全ての値をそれぞれのデフォルトに設定しています。

これらの値を構成するためには、独自の Agent オブジェクトを作成する必要が あります。

var http = require('http');
var keepAliveAgent = new http.Agent({ keepAlive: true });
keepAliveAgent.request(options, onResponseCallback);

agent.maxSockets#

デフォルトでは無制限に設定されます。 エージェントがいくつのソケットを並行にオープンするかを決定します。

agent.maxFreeSockets#

デフォルトでは 256 に設定されます。 HTTP キープアライブをサポートするエージェントでは、 空いた状態でオープンしたままにされるソケットの最大数を設定します。

agent.sockets#

エージェントが現在使っているソケットの配列です。 変更しないでください。

agent.freeSockets#

HTTP キープアライブが使われているエージェントの場合、使われるのを待っている ソケットの配列です。変更しないでください。

agent.requests#

まだソケットが割り当てられていないリクエストのキューを含むオブジェクトです。 変更しないでください。

agent.destroy()#

このエージェントで現在使用されているソケットを破棄します。

通常、これは必要ありません。 しかしながら、キープアライブが有効なエージェントを使用していて、 それがもう必要ないとわかっているなら、エージェントを明示的に シャットダウンするのがベストです。 そうでなければ、サーバがそれらを解放するまで、ソケットはとても長い時間 オープンしたままになるかもしれません。

agent.getName(options)#

接続が再利用できるかどうかを決定するために、リクエストのオプションから ユニークな名前を返します。 http のエージェントでは、これは host:port:localAddress です。 https のエージェントでは、名前は CA,証明書、暗号、その他 HTTPS/TLS に特有の オプションによってソケットの再利用性が決定されます。

http.globalAgent#

全ての HTTP クライアントリクエストで使用される、デフォルトの Agent のインスタンスです。

Class: http.ClientRequest#

このオブジェクトは HTTP サーバ内部で作成され、http.request() から返されます。 それはヘッダがキューに入れられた 進行中 のリクエストを表現します。 ヘッダは setHeader(name, value), getHeader(name), removeHeader(name) API によってまだ可変のままです。 実際にヘッダが送信されるのは、最初のデータチャンクが送信される時またはコネクションがクローズされる時です。

レスポンスを取得するには、'response' 用のリスナーをリクエストオブジェクトに加えます。 'response' イベントはレスポンスヘッダを受信するとリクエストオブジェクトによって生成されます。 'response' イベントは http.IncomingMessage のインスタンスを 唯一の引数として実行されます。

'response' イベントの間、レスポンスオブジェクトにリスナーを加えることができます; とりわけ 'data' イベントのリスナーです。

'response' ハンドラが加えられない場合、レスポンスは完全に捨てられます。 しかし、'response' イベントハンドラを加えた場合は、 'readable' イベントが発生した時に response.read() を呼ぶか、 'data' ハンドラを加えるか、.resume() メソッドを呼び出すかのいずれかにより、 レスポンスオブジェクトからのデータを消費しなければ なりません 。 データが消費されるまで、'end' イベントは生成されません。 また、データは読まれるまでメモリを消費し、'process out of memory' エラーにつながることになります。

注意: Node は Content-Length と実際に送信されたリクエストボディの長さが等しいかどうかチェックしません。

リクエストは Writable Stream インタフェースを実装します。 これは以下のイベントを持つ EventEmitter です。

Event: 'response'#

function (response) { }

このリクエストに対するレスポンスを受信した時に生成されます。 このイベントは一回だけ生成されます。 response 引数は http.IncomingMessage のインスタンスです。

オプション:

  • host: リクエストを発行するサーバのドメイン名または IP アドレス。
  • port: リモートサーバのポート。
  • soocketPath: Unix ドメインソケット (host:port または socketPath のどちらか)

Event: 'socket'#

function (socket) { }

このリクエストにソケットが割り当てられた後に生成されます。

Event: 'connect'#

function (response, socket, head) { }

サーバが CONNECT メソッドの要求に応答する度に生成されます。 このイベントが監視されていない場合、クライアントが CONNECT メソッドへの レスポンスを受信すると、そのコネクションはクローズされます。

どのように connect イベントを監視するかを示すクライアントとサーバのペア:

var http = require('http');
var net = require('net');
var url = require('url');

// Create an HTTP tunneling proxy
var proxy = http.createServer(function (req, res) {
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.end('okay');
});
proxy.on('connect', function(req, cltSocket, head) {
  // connect to an origin server
  var srvUrl = url.parse('http://' + req.url);
  var srvSocket = net.connect(srvUrl.port, srvUrl.hostname, function() {
    cltSocket.write('HTTP/1.1 200 Connection Established\r\n' +
                    'Proxy-agent: Node-Proxy\r\n' +
                    '\r\n');
    srvSocket.write(head);
    srvSocket.pipe(cltSocket);
    cltSocket.pipe(srvSocket);
  });
});

// now that proxy is running
proxy.listen(1337, '127.0.0.1', function() {

  // make a request to a tunneling proxy
  var options = {
    port: 1337,
    hostname: '127.0.0.1',
    method: 'CONNECT',
    path: 'www.google.com:80'
  };

  var req = http.request(options);
  req.end();

  req.on('connect', function(res, socket, head) {
    console.log('got connected!');

    // make a request over an HTTP tunnel
    socket.write('GET / HTTP/1.1\r\n' +
                 'Host: www.google.com:80\r\n' +
                 'Connection: close\r\n' +
                 '\r\n');
    socket.on('data', function(chunk) {
      console.log(chunk.toString());
    });
    socket.on('end', function() {
      proxy.close();
    });
  });
});

Event: 'upgrade'#

function (response, socket, head) { }

サーバがアップグレード要求に応答する度に生成されます。 このイベントが監視されていない場合、クライアントがアップグレードヘッダを受信するとそのコネクションはクローズされます。

どのように upgrade イベントを監視するかを示すクライアントとサーバのペア:

var http = require('http');

// Create an HTTP server
var srv = http.createServer(function (req, res) {
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.end('okay');
});
srv.on('upgrade', function(req, socket, head) {
  socket.write('HTTP/1.1 101 Web Socket Protocol Handshake\r\n' +
               'Upgrade: WebSocket\r\n' +
               'Connection: Upgrade\r\n' +
               '\r\n');

  socket.pipe(socket); // echo back
});

// now that server is running
srv.listen(1337, '127.0.0.1', function() {

  // make a request
  var options = {
    port: 1337,
    hostname: '127.0.0.1',
    headers: {
      'Connection': 'Upgrade',
      'Upgrade': 'websocket'
    }
  };

  var req = http.request(options);
  req.end();

  req.on('upgrade', function(res, socket, upgradeHead) {
    console.log('got upgraded!');
    socket.end();
    process.exit(0);
  });
});

Event: 'continue'#

function () { }

通常、リクエストが 'Expect: 100-continue' を含んでいたことにより、 サーバが '100 Continue' HTTP レスポンスを送信することで生成されます。 これはクライアントがリクエストボディを送信すべき事を示します。

request.write(chunk, [encoding])#

ボディのチャンクを送信します。 このメソッドを何回も呼び出すと、サーバへのリクエストボディをストリーム化できます - このケースは ['Transfer-Encoding', 'chunked'] ヘッダでリクエストを生成したことを意味します。

chunk 引数は Buffer または文字列です。

encoding 引数はオプションで、chunk が文字列の場合だけ適用されます。 デフォルトは 'utf8' です。

request.end([data], [encoding])#

リクエストの送信を終了します。 ボディのいくつかの部分がまだ送信されていない場合、それはストリームにフラッシュされます。 リクエストがチャンク化されている場合、これは終端の '0\r\n\r\n' を送信します。

data が指定された場合は、 request.write(data, encoding) に続けて request.end() を呼び出すのと等価です。

request.abort()#

リクエストをアボートします (v0.3.8 からの新機能)

request.setTimeout(timeout, [callback])#

このリクエストにソケットが割り当てられて接続した際に、 socket.setTimeout() が呼び出されます。

request.setNoDelay([noDelay])#

このリクエストにソケットが割り当てられて接続した際に、 socket.setNoDelay() が呼び出されます。

request.setSocketKeepAlive([enable], [initialDelay])#

このリクエストにソケットが割り当てられて接続した際に、 socket.setKeepAlive() が呼び出されます。

http.IncomingMessage#

IncomingMessage オブジェクトは http.Server または http.ClientRequest によって作成され、'request' および 'response' イベントそれぞれの 最初の引数として渡されます。 それはステータス、ヘッダ、およびデータにアクセスするために使われます。

これは Readable Stream インタフェースの実装で、 以下のイベント、メソッド、およびプロパティを追加で持ちます。

Event: 'close'#

function () { }

下層の接続が切断されたことを示します。 'end' と同様、このイベントはレスポンス毎に一度だけ生成されます。

'end' のように、このイベントはレスポンス毎に一回生成され、 'data' イベントはそれ以上生成されません。 http.ServerResponse'close' イベントにより多くの情報があります。

message.httpVersion#

サーバリクエストの場合、クライアントが送信した HTTP バージョンです。 クライアントレスポンスの場合、接続したサーバの HTTP バージョンです。 いずれの場合も '1.1' または '1.0' です。

同様に response.httpVersionMajor は最初の整数、 response.httpVersionMinor は 2 番目の整数です。

message.headers#

リクエスト/レスポンスヘッダオブジェクトです。

ヘッダ名と値のリードオンリーなマップです。ヘッダ名は小文字です。 例:

// Prints something like:
//
// { 'user-agent': 'curl/7.22.0',
//   host: '127.0.0.1:8000',
//   accept: '*/*' }
console.log(request.headers);

message.rawHeaders#

受信したものと正確に等しい生のリクエスト/レスポンスヘッダのリストです。

キーと値は同じリストに含まれることに注意してください。 これはタプルのリストでは ありません 。 すなわち、偶数番目はキーで、奇数番目は関連づけられた値です。

ヘッダの名前は小文字化されず、重複はマージされません。

// Prints something like:
//
// [ 'user-agent',
//   'this is invalid because there can be only one',
//   'User-Agent',
//   'curl/7.22.0',
//   'Host',
//   '127.0.0.1:8000',
//   'ACCEPT',
//   '*/*' ]
console.log(request.rawHeaders);

message.trailers#

リクエスト/レスポンスのトレーラオブジェクトです。 'end' イベントが生成されて以降のみ存在します。

message.rawTrailers#

受信したものと正確に等しい生のリクエスト/レスポンストレーラのリストです。 'end' イベントが生成されて以降のみ存在します。

message.setTimeout(msecs, callback)#

  • msecs Number
  • callback Function

message.connection.setTimeout(msecs, callback) を呼びます。

message.method#

http.Server から得たリクエストでのみ有効です

リクエストメソッドを表す文字列です。参照のみ可能です。 例: 'GET''DELETE'

message.url#

http.Server から得たリクエストでのみ有効です

リクエスト URL を表す文字列です。 これは実際の HTTP リクエストに存在する URL だけを含みます。 もしリクエストが:

GET /status?name=ryan HTTP/1.1\r\n
Accept: text/plain\r\n
\r\n

この場合の request.url はこうなります:

'/status?name=ryan'

URL の要素を解析したい場合は、 require('url').parse(request.url) を参照してください。例:

node> require('url').parse('/status?name=ryan')
{ href: '/status?name=ryan',
  search: '?name=ryan',
  query: 'name=ryan',
  pathname: '/status' }

問い合わせ文字列からパラメータを取り出したい場合は、 require('querystring').parse 関数を参照するか、 require('url').parse の第 2 引数に true を渡してください。例:

node> require('url').parse('/status?name=ryan', true)
{ href: '/status?name=ryan',
  search: '?name=ryan',
  query: { name: 'ryan' },
  pathname: '/status' }

message.statusCode#

http.ClientRequest から得たレスポンスでのみ有効です

3 桁の数字によるレスポンスのステータスコードです。例えば 404

message.statusMessage#

http.ClientRequest から得たレスポンスでのみ有効です

HTTP レスポンスのステータスメッセージ (reason phrase)。 例: OKInternal Server Error

message.socket#

コネクションに関連づけられた net.Socket オブジェクトです。

HTTPS では request.connection.verifyPeer()request.connection.getPeerCertificate() で クライアントの認証の詳細を取得できます。

HTTPS#

Stability: 3 - Stable

HTTPS は TLS/SSL 上の HTTP プロトコルです。 Node ではこれらは別のモジュールとして実装されています。

Class: https.Server#

このクラスは tls.Server のサブクラスで、http.Server と同様のイベントを生成します。 より詳しくは http.Server を参照してください。

server.setTimeout(msecs, callback)#

http.Server#setTimeout() を参照してください。

server.timeout#

新しい HTTPS Web サーバオブジェクトを返します。 optiontls.createServer() と同じです。 requestListener は関数で、 'request' イベントに自動的に追加されます。

例:

// curl -k https://localhost:8000/
var https = require('https');
var fs = require('fs');

var options = {
  key: fs.readFileSync('test/fixtures/keys/agent2-key.pem'),
  cert: fs.readFileSync('test/fixtures/keys/agent2-cert.pem')
};

https.createServer(options, function (req, res) {
  res.writeHead(200);
  res.end("hello world\n");
}).listen(8000);

または:

var https = require('https');
var fs = require('fs');

var options = {
  pfx: fs.readFileSync('server.pfx')
};

https.createServer(options, function (req, res) {
  res.writeHead(200);
  res.end("hello world\n");
}).listen(8000);

server.listen(port, [host], [backlog], [callback])#

server.listen(path, [callback])#

server.listen(handle, [callback])#

詳細は http.listen() を参照してください。

server.close([callback])#

See http.close() for details.

詳細は http.close() を参照してください。

https.request(options, callback)#

セキュアな Web サーバへのリクエストを作成します。

options はオブジェクトまたは文字列です。 options が文字列なら、それは自動的に url.parse() によって解析されます。

http.request() の全てと同様のオプションが指定できます。

例:

var https = require('https');

var options = {
  hostname: 'encrypted.google.com',
  port: 443,
  path: '/',
  method: 'GET'
};

var req = https.request(options, function(res) {
  console.log("statusCode: ", res.statusCode);
  console.log("headers: ", res.headers);

  res.on('data', function(d) {
    process.stdout.write(d);
  });
});
req.end();

req.on('error', function(e) {
  console.error(e);
});

options 引数は以下のオプションを持ちます。

  • host: リクエストを発行するサーバのドメイン名または IP アドレス。
  • hostname: url.parse() で扱える文字列をサポートします。 hostnamehost を上書きします。
  • port: リモートサーバのポート。デフォルトは 443 です。
  • method: HTTPS リクエストのメソッドの文字列。デフォルトは 'GET' です。
  • path: リクエストのパス。デフォルトは '/' です。 必要なら問い合わせ文字列を含めるべきです. 例 '/index.html?page=12'
  • headers: リクエストヘッダを含むオブジェクト。
  • auth: べーしく認証すなわち Authorization ヘッダのための 'user:password'
  • agent: Agent の振る舞いを制御します。 エージェントが使われる場合、Connection:keep-alive がデフォルトになります。 可能な値は:
    • undefined (デフォルト): ホストとポートで globalAgent を使用します。
    • Agent オブジェクト: 明示的に渡された Agent を使用します。
    • false: Agent によるコネクションプーリングを使用しません。 Connection:close の場合のデフォルトです。

以下の tls.connect() 由来のオプションを指定することもできますが、 グローバル globalAgent はこれらを無視します。

  • pfx: SSL で使用する証明書、秘密鍵、認証局の証明書。 デフォルトは null です。
  • key: SSL で使用する秘密鍵。デフォルトは null です。
  • passphrase: 秘密鍵または pfx のパスフレーズを表す文字列。 デフォルトは null です。
  • cert: x509公開証明書。デフォルトは null です。
  • ca: リモートホストをチェックする信頼できる認証局または認証局の配列。
  • ciphers: 使用または除外する暗号を記述した文字列。 詳細は http://www.openssl.org/docs/apps/ciphers.html#CIPHER_LIST_FORMAT を参照してください。
  • rejectUnauthorized: true の場合、サーバ証明書は提供された認証局の リストによって検証されます。 認証されなかった場合は 'error' イベントが生成されます。 認証は HTTP リクエストが送信される にコネクションレベルで行われます。 デフォルトは true です。
  • secureProtocol: 使用する SSL メソッド、たとえば SSLv3_method は SSL version 3 の使用を強制します。可能な値は使用する OpenSSL によって 定義される SSL_METHODS 定数に依存します。

これらのオプションを指定するには、カスタムエージェントを使用します。

例:

var options = {
  hostname: 'encrypted.google.com',
  port: 443,
  path: '/',
  method: 'GET',
  key: fs.readFileSync('test/fixtures/keys/agent2-key.pem'),
  cert: fs.readFileSync('test/fixtures/keys/agent2-cert.pem')
};
options.agent = new https.Agent(options);

var req = https.request(options, function(res) {
  ...
}

あるいは、エージェントを使用しません。

例:

var options = {
  hostname: 'encrypted.google.com',
  port: 443,
  path: '/',
  method: 'GET',
  key: fs.readFileSync('test/fixtures/keys/agent2-key.pem'),
  cert: fs.readFileSync('test/fixtures/keys/agent2-cert.pem'),
  agent: false
};

var req = https.request(options, function(res) {
  ...
}

https.get(options, callback)#

http.get() と同様ですが HTTPS です。

options はオブジェクトまたは文字列です。 options が文字列なら、それは自動的に url.parse() によって解析されます。

例:

var https = require('https');

https.get('https://encrypted.google.com/', function(res) {
  console.log("statusCode: ", res.statusCode);
  console.log("headers: ", res.headers);

  res.on('data', function(d) {
    process.stdout.write(d);
  });

}).on('error', function(e) {
  console.error(e);
});

Class: https.Agent#

HTTPS 用の Agent オブジェクトで,http.Agent と同様です。 詳細は https.request() を参照してください。

https.globalAgent#

全ての HTTPS クライアントリクエストで使用される、デフォルトの https.Agent のインスタンスです。

URL#

Stability: 3 - Stable

このモジュールはURLの解決や解析の為のユーティリティを持ちます。 利用するには require('url') を呼び出してください。

解析されたURLオブジェクトは、URL文字列の中に存在するかどうかに応じて 次に示すフィールドをいくつかもしくは全てを持ちます。 URL文字列に含まれないフィールドは解析結果のオブジェクトに含まれません。 次のURLで例を示します。

'http://user:pass@host.com:8080/p/a/t/h?query=string#hash'

  • href: 解析する前の完全な URL。protocol と host はどちらも小文字化されます。

    例: 'http://user:pass@host.com:8080/p/a/t/h?query=string#hash'

  • protocol: リクエストのプロトコル。小文字化されます。

    例: 'http:'

  • host: URL の完全で小文字化されたホスト情報。ポート番号を含みます。

    例: 'host.com:8080'

  • auth: URL の認証情報。

    例: 'user:pass'

  • hostname: ホスト情報の中の小文字化されたホスト名。

    例: 'host.com'

  • port: ホスト情報の中のポート番号。

    例: '8080'

  • pathname: URL のパス部分。ホスト情報からクエリまでの間に位置し、 最初にスラッシュが存在する場合はそれも含みます。

    例: '/p/a/t/h'

  • search: URL のクエリ文字列。先頭の ? マークも含みます。

    例: '?query=string'

  • path: pathnamesearch を連結した文字列。

    例: '/p/a/t/h?query=string'

  • query: クエリの変数部分の文字列、もしくはクエリ文字列を解析した オブジェクト。

    例: 'query=string' or {'query':'string'}

  • hash: URL の # マークを含む部分。

    例: '#hash'

以下のメソッドはURLモジュールにより提供されます:

url.parse(urlStr, [parseQueryString], [slashesDenoteHost])#

URL文字列を引数に取り、解析結果のオブジェクトを返します。

querystring モジュールを使ってクエリ文字列も解析したい場合は、 第 2 引数に true を渡してください。 デフォルトは false です。

//foo/bar{ pathname: '//foo/bar' } ではなく { host: 'foo', pathname: '/bar' } としたい場合は、 第 3 引数に true を渡してください。 デフォルトは false です。

url.format(urlObj)#

URL オブジェクトを引数に取り、フォーマットした URL 文字列を返します。

  • href は無視されます。
  • protocol の末尾に : (コロン) があってもなくても同じように扱われます。
    • httphttpsftpgopherfile は末尾に :// (コロン、スラッシュ、スラッシュ) が付けられます。
    • mailtoxmppaimsftpfoo など、その他のプロトコルは末尾に : (コロン) が付けられます。
  • auth が与えられると使われます。
  • hostnamehost が与えられなかった場合だけ使われます。
  • porthost が与えられなかった場合だけ使われます。
  • hosthostnameport の位置で使われます。
  • pathname の先頭に / (スラッシュ) があってもなくても同じように扱われます。
  • searchquery の位置で使われます。
  • query (文字列ではなくオブジェクトです; querystring を参照してください) は search が与えられなかった場合だけ使われます。
  • search の先頭に ? (クエスチョンマーク) があってもなくても同じように扱われます。
  • hash の先頭に # (シャープ, アンカー) があってもなくても同じように扱われます。

url.resolve(from, to)#

ベースとなる URL と相対 URL を引数に取り、ブラウザがアンカータグに対して行うのと同様に URL を解決します。例:

url.resolve('/one/two/three', 'four')         // '/one/two/four'
url.resolve('http://example.com/', '/one')    // 'http://example.com/one'
url.resolve('http://example.com/one', '/two') // 'http://example.com/two'

Query String#

Stability: 3 - Stable

このモジュールはクエリ文字列を処理するユーティリティを提供します。 以下のメソッドから成ります:

querystring.stringify(obj, [sep], [eq])#

クエリオブジェクトを文字列へ直列化します。 オプションとしてデフォルトの区切り文字 (デフォルトは '&') と代入文字 (デフォルトは '=') を上書き指定できます。

例:

querystring.stringify({ foo: 'bar', baz: ['qux', 'quux'], corge: '' })
// returns
'foo=bar&baz=qux&baz=quux&corge='

querystring.stringify({foo: 'bar', baz: 'qux'}, ';', ':')
// returns
'foo:bar;baz:qux'

querystring.parse(str, [sep], [eq], [options])#

クエリ文字列をオブジェクトに復元します。 オプションとしてデフォルトの区切り文字 ('&') と代入文字 ('=') を上書き指定できます。

オプションオブジェクトは maxKeys を含むことができます (デフォルトは 1000 です)。それはキーを処理する上限として使われます。 0 を設定すると制限は取り除かれます。

例:

querystring.parse('foo=bar&baz=qux&baz=quux&corge')
// returns
{ foo: 'bar', baz: ['qux', 'quux'], corge: '' }

querystring.escape#

escape 関数は querystring.stringify で使用されていて、必要な場合にオーバーライドできるよう提供されています。

querystring.unescape#

unescape関数は querystring.parse で使用されていて、必要な場合にオーバーライドできるよう提供されています。

punycode#

Stability: 2 - Unstable

Punycode.js は Node.js v0.6.2 以降に バンドルされています。 アクセスするには require('punycode') を使用します (他のバージョンの Node.js でこれを使用するには、先に npm を使用して punycode モジュールをインストールしてください)。

punycode.decode(string)#

ASCII 文字のみによる Punycode 文字列を Unicode 文字による文字列に変換します。

// decode domain name parts
punycode.decode('maana-pta'); // 'mañana'
punycode.decode('--dqo34k'); // '☃-⌘'

punycode.encode(string)#

Unicode 文字による文字列を ASCII 文字による Punycode 文字列に変換します。

// encode domain name parts
punycode.encode('mañana'); // 'maana-pta'
punycode.encode('☃-⌘'); // '--dqo34k'

punycode.toUnicode(domain)#

Punycode 文字列で表現されたドメイン名を Unicode に変換します。 ドメイン名の中の Punycode 化された文字列だけが変換されます。 そのため、すでに Unicode に変換された文字列でも気にせずに渡すことができます。

// decode domain names
punycode.toUnicode('xn--maana-pta.com'); // 'mañana.com'
punycode.toUnicode('xn----dqo34k.com'); // '☃-⌘.com'

punycode.toASCII(domain)#

Unicode 文字列で表現されたドメイン名を Punycode に変換します。 ドメイン名の中の非 ASCII 文字だけが変換されます。 すなわち、すでに ASCII 化されたドメインでも気にせずに渡すことができます。

// encode domain names
punycode.toASCII('mañana.com'); // 'xn--maana-pta.com'
punycode.toASCII('☃-⌘.com'); // 'xn----dqo34k.com'

punycode.ucs2#

punycode.ucs2.decode(string)#

文字列中の Unicode 文字のコードポイントに対応する数値を含む配列を作成します。 JavaScript uses UCS-2 internally のように、この関数はサロゲートペア (それぞれは 16bit の独立した文字) を 対応する Unicode の一つのコードポイントに変換します。

punycode.ucs2.decode('abc'); // [0x61, 0x62, 0x63]
// surrogate pair for U+1D306 tetragram for centre:
punycode.ucs2.decode('\uD834\uDF06'); // [0x1D306]

punycode.ucs2.encode(codePoints)#

コードポイントの数値を含む配列を元に文字列を作成します。

punycode.ucs2.encode([0x61, 0x62, 0x63]); // 'abc'
punycode.ucs2.encode([0x1D306]); // '\uD834\uDF06'

punycode.version#

現在の Punycode.js のバージョン番号を表す文字列です。

Readline#

Stability: 2 - Unstable

このモジュールを使用するには、require('readline') をします。 Readline はストリーム (たとえば process.stdin) を行ごとに読み込むことを可能にします。

このモジュールを一度起動すると、このインタフェースを クローズするまで node プログラムは終了しないことに注意してください。 プログラムをスムーズに終了する方法を以下に示します:

var readline = require('readline');

var rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout
});

rl.question("What do you think of node.js? ", function(answer) {
  // TODO: Log the answer in a database
  console.log("Thank you for your valuable feedback:", answer);

  rl.close();
});

readline.createInterface(options)#

行を読み込む Interface のインスタンスを作成します。 以下の値を含む options オブジェクトを受け取ります。

  • input - 監視する入力ストリーム (必須)。

  • output - 読み込んだデータを書くための出力ストリーム (必須)。

  • completer - タブによる自動補完のための関数 (オプション)。 後述の例を参照してください。

  • terminal - input および output ストリームが TTY デバイスで、 ANSI/VT100 エスケープコードを出力する場合は true を渡します。 デフォルトはインスタンス生成時に output に対して isTTY でチェックします。

completer 関数にはユーザが入力した現在の行が与えられ、 2 つのエントリを含む配列を返すことが期待されます:

  1. 補完によってマッチするエントリの配列。

  2. マッチングに使用された部分文字列。

それは次のようになります: [[substr1, substr2, ...], originalsubstring]

例:

function completer(line) {
  var completions = '.help .error .exit .quit .q'.split(' ')
  var hits = completions.filter(function(c) { return c.indexOf(line) == 0 })
  // show all completions if none found
  return [hits.length ? hits : completions, line]
}

completer が二つの引数を持つなら、それは非同期モードで実行されます。

function completer(linePartial, callback) {
  callback(null, [['123'], linePartial]);
}

createInterface には通常、ユーザからの入力を受け取るために process.stdinprocess.stdout が使用されます。

var readline = require('readline');
var rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout
});

readline のインスタンスを作成すると、ほとんどの場合 'line' イベントを 監視することになります。

もしこのインスタンスの terminaltrue の場合、 output ストリームはもし outout.columns プロパティが定義されていれば それに適合し、カラム幅が変更されると output 上で 'resize' イベントが生成されます (process.stdout が TTY の場合、それは自動的に行われます)。

Class: Interface#

入力と出力を持つ readline インタフェースを表現するクラスです。

rl.setPrompt(prompt)#

プロンプトを設定します。 たとえば、コマンドプロンプトで node コマンドを実行すると、 > を見ることができます。これが Node のプロンプトです。

rl.prompt([preserveCursor])#

ユーザからの入力を 1 行読み込みます。 現在の setPrompt() の値を新しい行に出力し、 ユーザに新しい入力エリアを与えます。 preserveCursortrue に設定すると、カーソル位置が 0 にリセットされなくなります。

これは、 createInterface() によって使われる input ストリームが 中断されていれば再開します。

rl.question(query, callback)#

query をプロンプトとして、ユーザが応答すると callback を起動します。 ユーザに質問を表示し、ユーザが応答をタイプすると、callback が起動されます。

これは、 createInterface() によって使われる input ストリームが 中断されていれば再開します。

使用例:

interface.question('What is your favorite food?', function(answer) {
  console.log('Oh, so your favorite food is ' + answer);
});

rl.pause()#

input ストリームからの入力を中断します。 必要なら後で再開することができます。

rl.resume()#

input ストリームからの入力を再開します。

rl.close()#

Interface のインスタンスをクローズし、input および output ストリームの 制御を解放します。'close' イベントも生成されます。

rl.write(data, [key])#

dataoutput ストリームに出力します。 key はキーシーケンスを表現するオブジェクトリテラルです; ターミナルが TTY の場合に有効です。

これは、input ストリームが中断されていれば再開します。

例:

rl.write('Delete me!');
// Simulate ctrl+u to delete the line written previously
rl.write(null, {ctrl: true, name: 'u'});

Events#

Event: 'line'#

function (line) {}

input ストリームから \n を読み込むごとに生成されます。 通常、ユーザがエンターまたはリターンを打つごとに受信します。 これはユーザ入力のよいフックとなります。

line を監視する例:

rl.on('line', function (cmd) {
  console.log('You just typed: '+cmd);
});

Event: 'pause'#

function () {}

input ストリームが中断されたときに生成されます。

input ストリームが中断されていない時に SIGCONT イベントを受信した際にも 生成されます (SIGTSTP および SIGCONT も参照してください)。

'pause' を監視する例:

rl.on('pause', function() {
  console.log('Readline paused.');
});

Event: 'resume'#

function () {}

input ストリームが再開された時に生成されます。

'resume' を監視する例:

rl.on('resume', function() {
  console.log('Readline resumed.');
});

Event: 'close'#

function () {}

close() が呼ばれた場合に生成されます。

input ストリームが 'end' イベントを受け取った場合にも生成されます。 これが生成された後、Interface インスタンスは完了したと考えられるべきです。 例えば、input ストリームが EOT として知られる ^D を受け取った場合。

このイベントは SIGINT イベントリスナが与えられていない場合に、 input ストリームが SIGINT として知られる ^C を受け取った場合にも 生成されます。

Event: 'SIGINT'#

function () {}

input ストリームが SIGINT として知られる ^C を受信した場合に 生成されます。 もし input ストリームが SIGINT を受信した時に 'SIGINT' イベントの リスナが存在しなければ、'pause' イベントがトリガされます。

'SIGINT' を監視する例:

rl.on('SIGINT', function() {
  rl.question('Are you sure you want to exit?', function(answer) {
    if (answer.match(/^y(es)?$/i)) rl.pause();
  });
});

Event: 'SIGTSTP'#

function () {}

これは Windows では動作しません。

input ストリームが SIGTSTP として知られる ^Z を受信した場合に 生成されます。 もし input ストリームが SIGTSTP を受信した時に 'SIGTSTP' イベントの リスナが存在しなければ、プログラムはバックグラウンドに送られます。

プログラムが fg により再開されると、'pause' および 'SIGCONT' イベントが 生成されます。どちらもストリームを再開するために使うことができます。

プログラムがバックグラウンドに送られる前にストリームが中断されていると、 'pause' および 'SIGCONT' イベントは生成されません。

'SIGTSTP' を監視する例:

rl.on('SIGTSTP', function() {
  // This will override SIGTSTP and prevent the program from going to the
  // background.
  console.log('Caught SIGTSTP.');
});

Event: 'SIGCONT'#

function () {}

これは Windows では動作しません。

input ストリームが SIGTSTP として知られる ^Z によってバックグラウンドに 送られた後で、fg(1) によって再開されるた場合に生成されます。 このイベントはプログラムがバックグラウンドに送られる前にストリームが中断されていなかった場合にのみ生成されます。

'SIGCONT' を監視する例:

rl.on('SIGCONT', function() {
  // `prompt` will automatically resume the stream
  rl.prompt();
});

Example: Tiny CLI#

全てを一緒に使う、小さなコマンドラインインタフェースの例:

var readline = require('readline'),
    rl = readline.createInterface(process.stdin, process.stdout);

rl.setPrompt('OHAI> ');
rl.prompt();

rl.on('line', function(line) {
  switch(line.trim()) {
    case 'hello':
      console.log('world!');
      break;
    default:
      console.log('Say what? I might have heard `' + line.trim() + '`');
      break;
  }
  rl.prompt();
}).on('close', function() {
  console.log('Have a great day!');
  process.exit(0);
});

readline.cursorTo(stream, x, y)#

カーソルを与えられた TTY スクリーンの指定の位置に移動します。

readline.moveCursor(stream, dx, dy)#

カーソルを与えられた TTY スクリーンの現在の位置からの相対位置に移動します。

readline.clearLine(stream, dir)#

与えられた TTY スクリーンの現在の行を指定された方向に消去します。 dir は以下の値のいずれか:

  • -1 - カーソルから左方向
  • 1 - カーソルから右方向
  • 0 - 行全体

readline.clearScreenDown(stream)#

スクリーンのカーソルより下を消去します。

REPL#

Stability: 3 - Stable

Read-Eval-Print-Loop (REPL) は単独のプログラムとしても他のプログラムに手軽に取り込む形でも利用することができます。 REPL は対話的に JavaScript を実行して結果を確認する手段を提供します。 デバッグやテストやその他の様々なことを試す用途で利用されます。

コマンドラインから node を引数無しで実行することで、REPL プログラムに入ります。 REPL は Emacs 風の簡易な行編集機能を備えています。

mjr:~$ node
Type '.help' for options.
> a = [ 1, 2, 3];
[ 1, 2, 3 ]
> a.forEach(function (v) {
...   console.log(v);
...   });
1
2
3

より進んだ行編集を行うには、環境変数に NODE_NO_READLINE=1 を設定してnodeを起動してください。 これによって main とデバッガ REPL を正規の端末設定で起動し、 rlwrap を利用することができます。

例として、bashrc ファイルに以下のように設定を追加します:

alias node="env NODE_NO_READLINE=1 rlwrap node"

repl.start(options)#

REPLServer インスタンスを作成して返します。 以下の値を含む "options" オブジェクトを受け取ります。
  • prompt - プロンプト。デフォルトは > です。

  • input - 監視する入力ストリーム。デフォルトは process.stdin です。

  • output - 読み込んだデータを書き込む出力ストリーム。 デフォルトは process.stdout です。

  • terminal - もし stream が TTY で、ANSI/VT100 エスケープコードを 出力するなら true。デフォルトはインスタンス作成時に output ストリームを isTTY でチェックします。

  • eval - 各行を評価するために使われる関数。デフォルトは eval() を 非同期にラップした関数です。 eval をカスタマイズする例は下記を参照してください。

  • useColors - write 関数が色を付けるかどうかを指定するブーリアン値。 writer に異なる関数が設定された場合、これは何もしません。 デフォルトは repl の terminal の値です。

  • useGlobal - もし true に設定されると、repl は独立したコンテキストを 使う代わりに global オブジェクトを使用します。デフォルトは false です。

  • ignoreUndefined - もし true に設定されると、repl はコマンドの戻り値が undefined だった場合にそれを出力しません。デフォルトは false です。

  • writer - コマンドが評価されるごとに実行される関数で、表示するために フォーマット (色づけも含みます) して返します。 デフォルトは util.inspect です。

以下のシグネチャを持つ独自の eval() 関数を使うことができます。

function eval(cmd, context, filename, callback) {
  callback(null, result);
}

複数の REPL を起動した場合、同一の node インスタンスが実行されないことがあります。 それぞれの REPL はグローバルオブジェクトを共有しますが、I/O は固有のものを持ちます。

REPL を標準入力、Unix ドメインソケット、TCP ソケットのもとで起動する例を示します:

var net = require("net"),
    repl = require("repl");

connections = 0;

repl.start({
  prompt: "node via stdin> ",
  input: process.stdin,
  output: process.stdout
});

net.createServer(function (socket) {
  connections += 1;
  repl.start({
    prompt: "node via Unix socket> ",
    input: socket,
    output: socket
  }).on('exit', function() {
    socket.end();
  })
}).listen("/tmp/node-repl-sock");

net.createServer(function (socket) {
  connections += 1;
  repl.start({
    prompt: "node via TCP socket> ",
    input: socket,
    output: socket
  }).on('exit', function() {
    socket.end();
  });
}).listen(5001);

このプログラムをコマンドラインから実行すると、標準入力のもとで REPL が起動します。 他の REPL クライアントは Unix ドメインソケットか TCP ソケットを介して接続することができます。 telnet が TCP ソケットへの接続に便利です。 socat は Unix ドメイン /TCP 両方のソケットへの接続に利用できます。

標準入力の代わりに Unix ドメインソケットをベースとしたサーバから REPL を起動することによって、 再起動することなく node の常駐プロセスへ接続することができます。

net.Server および net.Socket インスタンス上の "フル機能の" (terminal) REPL を実行する例は、https://gist.github.com/2209310 を参照してください。

curl(1) 上で REPL インスタンスを実行する例は、 https://gist.github.com/2053342 を参照してください。

Event: 'exit'#

function () {}

何らかの方法でユーザが REPL を終了した場合に生成されます。 すなわち、repl で .exit をタイプする、Ctrl+C を 2 回推して SIGINT を生成する、あるいは Ctrl+D を推して input ストリームで 'end' を 知らせるなどです。

'exit' を監視する例:

r.on('exit', function () {
  console.log('Got "exit" event from repl!');
  process.exit();
});

Event: 'reset'#

function (context) {}

REPL のコンテキストがリセットされた場合に生成されます。 これは .clear をタイプした時に発生します。 もし { useGlobal: true } を指定して repl を開始した場合、 このイベントは決して生成されません。

reset を監視する例:

// Extend the initial repl context.
r = repl.start({ options ... });
someExtension.extend(r.context);

// When a new context is created extend it as well.
r.on('reset', function (context) {
  console.log('repl has a new context');
  someExtension.extend(context);
});

REPL Features#

REPL の中で Control+D を実行すると終了します。複数行に渡る式を入力とすることができます。

特別な変数である _ (アンダースコア) は一番最後の式の結果を保持します。

> [ "a", "b", "c" ]
[ 'a', 'b', 'c' ]
> _.length
3
> _ += 1
4

REPL はグローバルスコープに存在する全ての変数にアクセス可能です。 それぞれの REPLServer に紐づく context オブジェクトに変数を付与することで、 明示的に変数を公開させることが可能です。 例:

// repl_test.js
var repl = require("repl"),
    msg = "message";

repl.start("> ").context.m = msg;

context オブジェクトに設定された変数は、REPL の中ではローカルな変数として現れます:

mjr:~$ node repl_test.js
> m
'message'

特別な REPL コマンドがいくつかあります:

  • .break - 複数行に渡って式を入力している間に、途中で分からなくなったり完了させなくても良くなることがあります。.break で最初からやり直します。
  • .clear - context オブジェクトを空の状態にリセットし、複数行に入力している式をクリアします。
  • .exit - I/Oストリームを閉じ、REPLを終了させます。
  • .help - このコマンドの一覧を表示します。
  • .save - 現在の REPL セッションをファイルに保存します。

    .save ./file/to/save.js

  • .load - 現在の REPL セッションにファイルをロードします。

    .load ./file/to/load.js

REPL では、以下のキーコンビネーションは特別な効果を持ちます

  • <ctrl>C - .break キーワードと同様です。 現在のコマンドを終了します。 強制的に終了したければ空の行で 2 回押してください。
  • <ctrl>D - .exit キーワードと同様です。

Executing JavaScript#

Stability: 3 - Stable

次のようにすることで、このモジュールにアクセスすることができます:

var vm = require('vm');

JavaScript コードは、コンパイルされてすぐに実行されるか、コンパイルおよび保存されて後から実行されます。

vm.runInThisContext(code, [options])#

vm.runInThisContext()code をコンパイルして実行し、結果を返します。 実行されるコードはローカルスコープにアクセスしませんが、現在の global オブジェクトにアクセスすることはできます。

vm.runInThisContexteval で同じコードを実行する例:

var localVar = 'initial value';

var vmResult = vm.runInThisContext('localVar = "vm";');
console.log('vmResult: ', vmResult);
console.log('localVar: ', localVar);

var evalResult = eval('localVar = "eval";');
console.log('evalResult: ', evalResult);
console.log('localVar: ', localVar);

// vmResult: 'vm', localVar: 'initial value'
// evalResult: 'eval', localVar: 'eval'

vm.runInThisContext() はローカルスコープにアクセスしないので、 localVar は変更されません。 eval() はローカルスコープにアクセスするので、localVar は変更されます。

この方法では、vm.runInThisContext()間接的な eval 呼び出し とほぼ同じですが (例: (0,eval)('code'))。 しかし、それに加えて以下のオプションがあります。

  • filename: 生成されるスタックトレースに表示されるファイル名を 制御することができます。
  • displayErrors: 例外をスローする前に、エラーの原因となったコードの行を ハイライトして標準エラー出力にプリントするか否か。 code をコンパイルした場合の文法エラーと、コンパイルされたコードを 実行した際のランタイムエラーの両方を捕まえます。
  • timeout: code の実行が終了するまでのミリ秒単位の時間。 もし実行が終了しなければ、Error がスローされます。

vm.createContext([sandbox])#

もし sandbox オブジェクトが与えられると、vm.runInContext()script.runInContext() の呼び出しで利用できるようにサンドボックスを 「コンテキスト化された」します。 実行中のスクリプト内では、sandbox はグローバルオブジェクトとなります。 それは存在するプロパティに加えて、標準の グローバルオブジェクト が持つ組込のオブジェクトや関数などを保持します。 vm モジュールによって実行されているスクリプトの外側では、sandbox は変更されません。

サンドボックスオブジェクトが与えられなかった場合は、 新しくて空のコンテキスト化されたサンドボックスオブジェクトが返されます。

この関数は複数のスクリプトから利用可能なサンドボックスを作るのに便利です。 たとえば、Webブラウザをエミュレートするためにグローバルオブジェクトである window を表現する単一のサンドボックスを作成し、全ての <script> タグを そのサンドボックス内で一緒に実行します。

vm.isContext(sandbox)#

サンドボックスオブジェクトが vm.createContext() によって コンテキスト化されているかどうかを返します。

vm.runInContext(code, contextifiedSandbox, [options])#

vm.runInContext() は、code をコンパイルしてそれを contextifiedSandbox の中で実行し、その結果を返します。 実行されるコードはローカルスコープにアクセスしません。 contextifiedSandbox オブジェクトは vm.createContext() を通じて事前に コンテキスト化されていなければなりません; それは code のグローバルオブジェクトとして使われます。

vm.runInContext()vm.runInThisContext() と同じオプションを受け取ります。

例: 異なるスクリプトを単一の既存コンテキスト中でコンパイルして実行します。

var util = require('util');
var vm = require('vm');

var sandbox = { globalVar: 1 };
vm.createContext(sandbox);

for (var i = 0; i < 10; ++i) {
    vm.runInContext('globalVar *= 2;', sandbox);
}
console.log(util.inspect(sandbox));

// { globalVar: 1024 }

<!- Note that running untrusted code is a tricky business requiring great care. vm.runInContext is quite useful, but safely running untrusted code requires a separate process. -->

信頼できないコードの実行は、細心の注意が求められることに注意してください。 vm.runInContext() は有用ですが、信頼できないコードを安全に実行するには 別のプロセスが必要となります。

vm.runInNewContext(code, [sandbox], [options])#

vm.runInNewContext()code をコンパイルし、sandbox が与えられれば それをコンテキスト化し、または省略された場合は新しいコンテキスト化された サンドボックスを作成し、サンドボックスをグローバルオブジェクトとしてコードを 実行し、その結果を返します。

vm.runInNewContext()vm.runInThisContext() と同じオプションを 受け取ります。

例: コードをコンパイルして実行し、グローバル変数をインクリメントし、 新しい値を設定します。そのグローバルはサンドボックスに含まれます。

var util = require('util');
var vm = require('vm'),

var sandbox = {
  animal: 'cat',
  count: 2
};

vm.runInNewContext('count += 1; name = "kitty"', sandbox);
console.log(util.inspect(sandbox));

// { animal: 'cat', count: 3, name: 'kitty' }

信頼できないコードの実行は、細心の注意が求められることに注意してください。 vm.runInNewContext() は有用ですが、信頼できないコードを安全に実行するには 別のプロセスが必要となります。

Class: Script#

事前にコンパイルされたスクリプトを保持し、指定されたサンドボックス中で 実行するためのクラスです。

new vm.Script(code, options)#

code をコンパイルして新しい Script を作成しますが、実行はしません。 作成された vm.Script オブジェクトはコンパイルされたコードを表現します。 スクリプトは後述するメソッドを使って後から何度でも実行することができます。 返されたスクリプトオブジェクトは、どのグローバルオブジェクトにも 束縛されていません。それは実行される前に、その実行だけに束縛されます。

スクリプトを作成するためのオプションは:

  • filename: 生成されるスタックトレースに表示されるファイル名を 制御することができます。
  • displayErrors: 例外をスローする前に、エラーの原因となったコードの行を ハイライトして標準エラー出力にプリントするか否か。 code をコンパイルした場合の文法エラーにだけ適用されます; コードを実行した際のエラーはスクリプトのメソッドに与えられる オプションによって制御されます。

script.runInThisContext([options])#

vm.runInThisContext() と似ていますが、事前にコンパイルされた Script オブジェクトのメソッドです。script.runInThisContext() はコンパイルされた script のコードを実行し、その結果を返します。 実行されるコードはローカルスコープにアクセスしませんが、現在の global オブジェクトにアクセスすることはできます。

script.runInThisContext() を使ってコードを一度だけコンパイルし、 複数回実行する例:

var vm = require('vm');

global.globalVar = 0;

var script = new vm.Script('globalVar += 1', { filename: 'myfile.vm' });

for (var i = 0; i < 1000; ++i) {
  script.runInThisContext();
}

console.log(globalVar);

// 1000

スクリプトを実行するためのオプションは:

  • displayErrors: 例外をスローする前に、実行時エラーの原因となったコードの行を ハイライトして標準エラー出力にプリントするか否か。 code を実行した場合の実行時エラーにだけ適用されます; Script のコンストラクタが例外をスローするため、文法エラーのある Script のインスタンスを生成することは不可能です。
  • timeout: code の実行が終了するまでのミリ秒単位の時間。 もし実行が終了しなければ、Error がスローされます。

script.runInContext(contextifiedSandbox, [options])#

vm.runInContext() と似ていますが、事前にコンパイルされた Script オブジェクトのメソッドです。script.runInContext() はコンパイルされた script のコードを contextifiedSandbox の中で実行し、その結果を返します。 実行されるコードはローカルスコープにアクセスしません。

script.runInContext()script.runInThisContext() と同じオプションを 受け取ります。

例: コードをコンパイルして実行し、グローバル変数をインクリメントし、 新しい値を設定します。そのグローバルはサンドボックスに含まれます。

var util = require('util');
var vm = require('vm');

var sandbox = {
  animal: 'cat',
  count: 2
};

var script = new vm.Script('count += 1; name = "kitty"');

for (var i = 0; i < 10; ++i) {
  script.runInContext(sandbox);
}

console.log(util.inspect(sandbox));

// { animal: 'cat', count: 12, name: 'kitty' }

信頼できないコードの実行は、細心の注意が求められることに注意してください。 script.runInContext() は有用ですが、信頼できないコードを安全に実行するには 別のプロセスが必要となります。

script.runInNewContext([sandbox], [options])#

vm.runInNewContext() と似ていますが、事前にコンパイルされた Script オブジェクトのメソッドです。 script.runInNewContext() は、sandbox が与えられればそれをコンテキスト化し、 または省略された場合は新しいコンテキスト化されたサンドボックスを作成し、 サンドボックスをグローバルオブジェクトとして script のコンパイルされたコードを 実行し、その結果を返します。 実行されるコードはローカルスコープにアクセスしません。

script.runInNewContext()script.runInThisContext() と同じオプションを 受け取ります。

例: グローバル変数を設定するコードをコンパイルし、異なったコンテキストで 複数回実行します。それらのグローバルはそれぞれのサンドボックスに設定されます。

var util = require('util');
var vm = require('vm');

var sandboxes = [{}, {}, {}];

var script = new vm.Script('globalVar = "set"');

sandboxes.forEach(function (sandbox) {
  script.runInNewContext(sandbox);
});

console.log(util.inspect(sandboxes));

// [{ globalVar: 'set' }, { globalVar: 'set' }, { globalVar: 'set' }]

信頼できないコードの実行は、細心の注意が求められることに注意してください。 script.runInNewContext() は有用ですが、信頼できないコードを安全に実行するには 別のプロセスが必要となります。

Child Process#

Stability: 3 - Stable

Nodeは child_process モジュールを通じて、3 方向の popen(3) 機能を提供します。

これは完全にノンブロッキングな方法で子プロセスの stdinstdout、 そして stderr を通じたデータストリームを実現します。 (いくつかのプログラムは内部的にバッファリングされた I/O を使うことに 注意してください。それは node.js には影響しませんが、 子プロセスに送ったデータがすぐに消費されるとは限らないことを意味します)。

子プロセスの生成は require('child_process').spawn() または require('child_process').fork() を使います。 それぞれの意味論は以下で説明するようにわずかに異なります。

Class: ChildProcess#

ChildProcessEventEmitter です。

子プロセスは常に 3 本のストリームと関連づけられています。 child.stdinchild.stdout、そして child.stderr です。 それらは親プロセスの標準入出力ストリームを共有するかもしれませんし、 独立したストリームオブジェクトにパイプでつながれているかもしれません。

Event: 'error'#

  • err {Error Object} エラー。

次の場合に生成されます:

  1. プロセスを起動できなかった、または
  2. プロセスを殺すことができなかった、または
  3. 何らかの理由で子プロセスにメッセージを送信することが失敗した。

エラーが発生した後、'exit' イベントは生成されることもあれば されないこともあることに注意してください。 もし両方のイベントを監視するなら、リスナ関数は2回呼び出されることに備えることを 忘れないでください。

ChildProcess#kill() および ChildProcess#send() も参照してください。

Event: 'exit'#

  • code {Number} 通常に終了した場合は終了コード。
  • signal {String} 親プロセスによって終了させられた場合は、 子プロセスを終了するために送られたシグナル。

このイベントは子プロセスが終了した後で生成されます。 プロセスが普通に終了した場合、code はプロセスの終了コードです。 それ以外の場合は null です。 プロセスがシグナルを受け取って終了した場合、signal は文字列によるシグナルの名前です。 それ以外の場合は null です。

子プロセスの標準入出力ストリームはオープンしたままになっているかも しれないことに注意してください。

また、Node が 'SIGINT' および 'SIGTERM' に対するシグナルハンドラを 確立するため、子プロセスがそれらのシグナルを受けとって終了しても、 signal` にはそれらのシグナルの名前が設定されないことに注意してください。

waitpid(2) を参照してください。

Event: 'close'#

  • code {Number} 普通に終了した場合は、その終了コード。
  • signal {String} 親プロセスによって殺された場合は、 子プロセスを殺すために渡されたシグナル。

このイベントは、子プロセスの標準入出力ストリームが全て終了した場合に 生成されます。 複数のプロセスが同じ標準入出力ストリームを共有するかもしれないので、 これは 'exit' とは明確に異なります。

Event: 'disconnect'#

このイベントは、親プロセスまたは子プロセスで .disconnect() メソッドが 呼び出された場合に生成されます。 切断の後では、プロセス間でメッセージを送信することはできず、 .connected プロパティは false になります。

Event: 'message'#

  • message {Object} 解析済みの JSON オブジェクトまたはプリミティブ値
  • sendHandle {Handle object} ソケットまたはサーバオブジェクト

.send(message, [sendHandle]) によって送信されたメッセージは 'message' イベントによって取得できます。

child.stdin#

  • Stream object

子プロセスの stdin を表現する Writable Stream です。 多くの場合、end() を通じてこのストリームを閉じると子プロセスが終了する原因となります。

子プロセスの標準入出力が親プロセスと共有されている場合は設定されません。

child.stdout#

  • Stream object

子プロセスの stdout を表現する Readable Stream です。

子プロセスの標準入出力が親プロセスと共有されている場合は設定されません。

child.stderr#

  • Stream object

子プロセスの stderr を表現する Readable Stream です。

子プロセスの標準入出力が親プロセスと共有されている場合は設定されません。

child.pid#

  • Integer

子プロセスの PID です。

例:

var spawn = require('child_process').spawn,
    grep  = spawn('grep', ['ssh']);

console.log('Spawned child pid: ' + grep.pid);
grep.stdin.end();

child.connected#

  • {Boolean} .disconnect' が呼び出されると false` に設定される

.connectedfalse の場合、メッセージを送信することはできません。

child.kill([signal])#

  • signal String

子プロセスにシグナルを送ります。 引数が与えられない場合、子プロセスには 'SIGTERM' が送られます。 利用可能なシグナルの一覧は signal(7) を参照してください。

var spawn = require('child_process').spawn,
    grep  = spawn('grep', ['ssh']);

grep.on('close', function (code, signal) {
  console.log('child process terminated due to receipt of signal '+signal);
});

// send SIGHUP to process
grep.kill('SIGHUP');

シグナルを送ることができなかった場合は 'error' イベントが 生成されるかもしれません。 既に終了した子プロセスへシグナルを送信してもエラーにはならず、 予想しない結果になるかもしれません: PID (プロセス ID) が他のプロセスに再割り当てされると、 シグナルはそのプロセスに送信されてしまいます。 それで何が起こるかは誰にも予想できません。

この関数は kill と呼ばれるものの、 子プロセスに届けられるシグナルが実際には子プロセスを殺さないかもしれないことに注意してください。 kill はただプロセスにシグナルを送るだけです。

kill(2) を参照してください。

child.send(message, [sendHandle])#

  • message Object
  • sendHandle Handle object

child_process.fork() を使うと、child.send(message, [sendHandle]) を 使って子プロセスにメッセージを送信し、子プロセスではそれを 'message' イベントによって受け取ることができます。

例:

var cp = require('child_process');

var n = cp.fork(__dirname + '/sub.js');

n.on('message', function(m) {
  console.log('PARENT got message:', m);
});

n.send({ hello: 'world' });

子プロセスの 'sub.js' は次のようになります:

process.on('message', function(m) {
  console.log('CHILD got message:', m);
});

process.send({ foo: 'bar' });

子プロセスでは process オブジェクトは send() メソッドを持ち、 そのチャネル上でメッセージを受信するたびにイベントを生成します。

親プロセスと子プロセスのいずれにおいても、send() メソッドは同期的です - データの大きな塊を送信することは推奨されません (代わりにパイプを使うことが出来ます、 child_process.spawn を参照してください)。

特別なケースとして、{cmd: 'NODE_foo'} のようなメッセージを 送信する場合があります。 cmd プロパティが接頭辞 NODE_ を含む全てのメッセージは node のコアで 使われる内部的なメッセージであるため、'message' イベントを生成しません。 この接頭辞を含むメッセージは 'internalMessage' イベントを生成しますが、 それを使用すべきではありません。それは保証なしに変更される可能性があります。

child.send()sendHandle オプションは TCP サーバまたは ソケットオブジェクトを他のプロセスに送信するためのものです。 子プロセスはそれを 'message' イベントの第 2 引数として受信します。

たとえば子プロセスが既に終了した場合など、メッセージを送信できなかった場合は 'error' イベントが生成されます。

Example: sending server object#

サーバを送信する例:

var child = require('child_process').fork('child.js');

// Open up the server object and send the handle.
var server = require('net').createServer();
server.on('connection', function (socket) {
  socket.end('handled by parent');
});
server.listen(1337, function() {
  child.send('server', server);
});

サーバオブジェクトを受信する子プロセス:

process.on('message', function(m, server) {
  if (m === 'server') {
    server.on('connection', function (socket) {
      socket.end('handled by child');
    });
  }
});

サーバは親プロセスと子プロセスで共有されることに注意してください。 これはコネクションが時には親あるいは子で処理されることを意味します。

dgram サーバのワークフローも同じです。 connection イベントの代わりに message イベントを監視し、 server.listen の代わりに server.bind を使用してください (現時点では UNIX プラットフォームでのみサポートされています)。

Example: sending socket object#

これはソケットを送信する例です。 これは二つの子プロセスを起動し、コネクションのリモートアドレスが VIP (74.125.127.100) ならソケットを "special" 子プロセスに送信します。 その他のソケットは "normal" プロセスに送られます。

var normal = require('child_process').fork('child.js', ['normal']);
var special = require('child_process').fork('child.js', ['special']);

// Open up the server and send sockets to child
var server = require('net').createServer();
server.on('connection', function (socket) {

  // if this is a VIP
  if (socket.remoteAddress === '74.125.127.100') {
    special.send('socket', socket);
    return;
  }
  // just the usual dudes
  normal.send('socket', socket);
});
server.listen(1337);

chold.js は次のようになります:

process.on('message', function(m, socket) {
  if (m === 'socket') {
    socket.end('You were handled as a ' + process.argv[2] + ' person');
  }
});

一度ソケットが子プロセスに送信されると、親プロセスはもうソケットがいつ 破棄されるか知ることができないことに注意してください。 この状態を示すために,.connections プロパティは null になります。 この状態では、.maxConnections も使わないことを推奨します。

child.disconnect()#

親プロセスと子プロセス間の IPC コネクションをクローズし、 他の接続を持たない子プロセスが自然に終了することを可能にします。 このメソッドを呼び出すと、親プロセスと子プロセスの両方で .connectedfalse に設定され、メッセージを送信することはできなくなります。

プロセスが受信するメッセージがなければ、おそらくはすぐに 'disconnect' イベントが生成されます。

子プロセスでも process.disconnect() を呼び出せることに注意してください。

child_process.spawn(command, [args], [options])#

  • command {String} 実行するコマンド
  • args {Array} 文字列による引数の配列
  • options {Object}
    • cwd {String} 子プロセスのカレントワーキングディレクトリ
    • stdio {Array|String} 子プロセスの標準入出力の設定 (後述)。
    • customFds {Array} Deprecated 子プロセスが標準入出力として使用する ファイル記述子の配列 (後述)
    • env {Object} 環境変数として与えるキー・値のペア
    • detached {Boolean} 子プロセスがプロセスグループのリーダになるかどうか (後述)。
    • uid {Number} このプロセスのユーザ識別子を設定します (setuid(2) を参照)。
    • gid {Number} このプロセスのグループ識別子を設定します (setgid(2) を参照)。
  • return: {ChildProcess object}

args をコマンドライン引数として、与えられた command で新しいプロセスを起動します。 args が省略された場合、空の配列がデフォルトとなります。

第 3 引数は追加のオプションを指定するために使われ、そのデフォルトは:

{ cwd: undefined,
  env: process.env
}

cwd で起動されたプロセスのワーキングディレクトリを指定することができます。 env は新しいプロセスに見える環境変数を指定するために使います。

ls -lh /usr を実行して stdoutstderr、および終了コードを取得する例:

var spawn = require('child_process').spawn,
    ls    = spawn('ls', ['-lh', '/usr']);

ls.stdout.on('data', function (data) {
  console.log('stdout: ' + data);
});

ls.stderr.on('data', function (data) {
  console.log('stderr: ' + data);
});

ls.on('close', function (code) {
  console.log('child process exited with code ' + code);
});

とても手の込んだ方法で実行する 'ps ax | grep ssh' の例:

var spawn = require('child_process').spawn,
    ps    = spawn('ps', ['ax']),
    grep  = spawn('grep', ['ssh']);

ps.stdout.on('data', function (data) {
  grep.stdin.write(data);
});

ps.stderr.on('data', function (data) {
  console.log('ps stderr: ' + data);
});

ps.on('close', function (code) {
  if (code !== 0) {
    console.log('ps process exited with code ' + code);
  }
  grep.stdin.end();
});

grep.stdout.on('data', function (data) {
  console.log('' + data);
});

grep.stderr.on('data', function (data) {
  console.log('grep stderr: ' + data);
});

grep.on('close', function (code) {
  if (code !== 0) {
    console.log('grep process exited with code ' + code);
  }
});

exec の失敗をチェックする例:

var spawn = require('child_process').spawn,
    child = spawn('bad_command');

child.stderr.setEncoding('utf8');
child.stderr.on('data', function (data) {
  if (/^execvp\(\)/.test(data)) {
    console.log('Failed to start child process.');
  }
});

spawn() は空の options オブジェクトを受け取ると、 process.env を使うのではなく,空の環境変数で子プロセスを起動します。 これは廃止された API との互換性のためです。

child_process.spawn()stdio オプションは配列で、 それぞれのインデックスは子プロセスの fd に対応します。 要素の値は以下のいずれかです:

  1. 'pipe' - 子プロセスと親プロセスの間でパイプを作成します。 パイプの親側の端点は child_process オブジェクトのプロパティ ChildProcess.stdio[fd] として親プロセスに公開されます。 fd 0~2 はそれぞれ、ChildProcess.stdinChildProcess.stdoutChildProcess.stderr としても参照可能です。
  2. 'ipc' - 親プロセスと子プロセスの間でメッセージパッシングのための IPC チャネル/ファイル記述子を作成します。 ChildProcess は標準入出力に高々一つの IPC ファイル記述子を持ちます。 このオプションを設定すると、ChildProcess.send() メソッドが有効になります。 子プロセスがこのファイル記述子に JSON メッセージを書き込むと、 それは ChildProcess.on('message') を引き起こします。 子プロセスが Node.js プログラムなら、IPC チャネルの存在は process.send() および process.on('message') を有効にします。
  3. 'ignore' - 子プロセスにファイル記述子を設定しません。 Node は子プロセスを起動する際、常に fd 0~2 をオープンすることに 注意してください。これらのうちのどれかが 'ignore' の場合、node は /dev/null をオープンして、それを子プロセスの fd に割り当てます。
  4. Stream オブジェクト - tty、ファイル、ソケット、またはパイプを参照する 読み込みまたは書き込み可能なストリームを子プロセスと共有します。 ストリームの下層にあるファイル記述子は、子プロセスの stdio 配列の 対応する位置にコピーされます。 ストリームは下層のファイル記述を持っていなければならないことに 注意してください (ファイルストリームは 'open' イベントが発生するまで それを持ちません)。
  5. 非負整数 - 整数の値を親プロセスが現在オープンしているファイル記述子として 解釈されます。 それは Stream オブジェクトの場合と同様に子プロセスに共有されます。
  6. nullundefined - デフォルト値を使用します。 stdiofd が 0、1、または 2 (言い換えると stdin、stdout、または stderr) の場合はパイプが作成されます。fd が 3 以上の場合、デフォルトは 'ignore' です。

簡易な記法として、stdio に配列ではなく以下の文字列の一つを指定することも できます。

  • ignore - ['ignore', 'ignore', 'ignore']
  • pipe - ['pipe', 'pipe', 'pipe']
  • inherit - [process.stdin, process.stdout, process.stderr] または [0,1,2]

例:

var spawn = require('child_process').spawn;

// Child will use parent's stdios
spawn('prg', [], { stdio: 'inherit' });

// Spawn child sharing only stderr
spawn('prg', [], { stdio: ['pipe', 'pipe', process.stderr] });

// Open an extra fd=4, to interact with programs present a
// startd-style interface.
spawn('prg', [], { stdio: ['pipe', null, null, null, 'pipe'] });

detached オプションが設定されると、子プロセスは新しいプロセスグループの リーダになります。 これは親プロセスが終了しても子プロセスの実行が継続することを可能にします。

デフォルトでは、親プロセスは切り離された子プロセスの終了を待機します。 親プロセスが child を待機することを防ぐには、child.unref() メソッドを 使用し、親のイベントループに子のリファレンスカウントが含まれないようにします。

長時間実行する子プロセスを切り離し、出力をファイルにリダイレクトする例:

 var fs = require('fs'),
     spawn = require('child_process').spawn,
     out = fs.openSync('./out.log', 'a'),
     err = fs.openSync('./out.log', 'a');

 var child = spawn('prg', [], {
   detached: true,
   stdio: [ 'ignore', out, err ]
 });

 child.unref();

長時間実行されるプロセスを開始するために detached オプションを使用する場合、 その stdio が親と接続するような構成を与えられない限り、そのプロセスは バックグラウンドにとどまりません。 親の stdio が継承されるなら、子プロセスは制御しているターミナルに 接続されたままです。

指定のファイル記述子を子プロセスの標準入出力に指定することを可能にする、 customFds と呼ばれる廃止されたオプションがありました。 この API は全てのプラットフォームに移植可能ではないために削除されました。 customFds は新しいプロセスの [stdin, stdout, stderr] を既存のストリームに接続することを可能にしました; -1 は新しいストリームが作られなければならないことを意味していました。 使用する場合は自己責任で。

関連項目: child_process.exec() および child_process.fork()

child_process.exec(command, [options], callback)#

  • command {String} 実行するコマンド、空白で区切られた引数を持ちます
  • options {Object}
    • cwd {String} 子プロセスのカレントワーキングディレクトリ
    • env {Object} 環境変数として与えるキー・値のペア
    • encoding {String} (Default: 'utf8')
    • shell {String} コマンドを実行するシェル (デフォルト: UNIX では 'bin/sh'、Windows では 'cmd.exe'。 シェルは UNIX では -c スイッチを、 Windows では /s /c を理解すべきです。 Windows では、コマンドラインの解析は cmd.exe と互換であるべきです)。
    • timeout {Number} (Default: 0)
    • maxBuffer {Number} (Default: 200*1024)
    • killSignal {String} (Default: 'SIGTERM')
  • callback {Function} プロセスが終了するとその出力を伴って呼び出されます
    • error {Error}
    • stdout {Buffer}
    • stderr {Buffer}
  • Return: ChildProcess object

コマンドをシェルで実行し、その出力をバッファに格納します。

var exec = require('child_process').exec,
    child;

child = exec('cat *.js bad_file | wc -l',
  function (error, stdout, stderr) {
    console.log('stdout: ' + stdout);
    console.log('stderr: ' + stderr);
    if (error !== null) {
      console.log('exec error: ' + error);
    }
});

コールバックは引数 (error, stdout, stderr) を得ます。 成功すると、errornull になります。 エラーだと、errorError のインスタンスとなり、 err.code は子プロセスの終了コード、 err.signal はプロセスを終了させたシグナルとなります。

任意の第 2 引数でいくつかのオプションを指定することができます。 オプションのデフォルトは

{ encoding: 'utf8',
  timeout: 0,
  maxBuffer: 200*1024,
  killSignal: 'SIGTERM',
  cwd: null,
  env: null }

もし timeout が 0 より大きいと、 子プロセスは実行時間が timeout ミリ秒よりも長くなると kill されます。 子プロセスは killSignal で kill されます (デフォルト: 'SIGTERM')。 maxBuffer は標準出力と標準エラーの最大のデータ量を指定します - この値を超えると子プロセスは kill されます。

child_process.execFile(file, [args], [options], [callback])#

  • file {String} 実行するプログラムのファイル名
  • args {Array} 文字列による引数の配列
  • options {Object}
    • cwd {String} 子プロセスのカレントワーキングディレクトリ
    • env {Object} 環境変数として与えるキー・値のペア
    • encoding {String} (Default: 'utf8')
    • timeout {Number} (Default: 0)
    • maxBuffer {Number} (Default: 200*1024)
    • killSignal {String} (Default: 'SIGTERM')
  • callback {Function} プロセスが終了するとその出力を伴って呼び出されます
    • error {Error}
    • stdout {Buffer}
    • stderr {Buffer}
  • Return: ChildProcess object

子シェルで実行する代わりに指定されたファイルを直接実行することを除いて child_process.exec() と同様です。 これは child_process.exec より若干効率的で、同じオプションを持ちます。

child_process.fork(modulePath, [args], [options])#

  • modulePath {String} 子プロセスで実行するモジュール
  • args {Array} 文字列による引数の配列
  • options {Object}
    • cwd {String} 子プロセスのカレントワーキングディレクトリ
    • env {Object} 環境変数として与えるキー・値のペア
    • encoding {String} (デフォルト: 'utf8')
    • execPath {String} 子プロセスの作成に使われる実行ファイル
    • execArgv {Array} 実行ファイルに渡される引数を表す文字列の配列 (デフォルトは process.execArgv)。
    • silent {Boolean} true の場合、子プロセスの標準入力、標準出力、 標準エラー出力は親プロセスにパイプされます。 そうでない場合は親プロセスから継承します。 より詳細は spawn()pipe および inherit オプションを参照してください (デフォルトは false)。
  • Return: ChildProcess object

これは spawn() の特別版で、Node プロセスを起動します。 返されるオブジェクトは通常の ChildProcess の全てのメソッドに加えて、 組み込みの通信チャネルを持ちます。 詳細は child.send(message, [sendHandle]) を参照してください。

これらの子 Node は、やはり V8 の新しいインスタンスです。 新しい Node ごとに少なくとも 30 ミリ秒の起動時間と 10MB のメモリを前提としてください。 つまり、数千の子プロセスを作ることは出来ません。

options オブジェクト中の execPath プロパティは、 現在の node 実行ファイルではない子プロセスの作成を可能にします。 デフォルトでは、子プロセスの環境変数 NODE_CHANNEL_FD によって示される ファイル記述子を通じて対話することに注意しなければなりません。 このファイル記述子における入力と出力は、改行で区切られた JSON オブジェクトです。

Assert#

Stability: 5 - Locked

このモジュールはアプリケーションの単体テストを記述するために使用され、 require('assert') でアクセスできます。

assert.fail(actual, expected, message, operator)#

actualexpectedoperator で区切ったメッセージを持つ例外を スローします。

assert(value, message), assert.ok(value, [message])#

value が truthy かテストします、 これは assert.equal(true, !!value, message); と等価です。

assert.equal(actual, expected, [message])#

== 演算子を強制して浅い同値性をテストします。

assert.notEqual(actual, expected, [message])#

!= 演算子を強制して浅い非同値性をテストします。

assert.deepEqual(actual, expected, [message])#

深い同値性をテストします。

assert.notDeepEqual(actual, expected, [message])#

深い非同値性をテストします。

assert.strictEqual(actual, expected, [message])#

=== 演算子で厳密な同値性をテストします。

assert.notStrictEqual(actual, expected, [message])#

!== 演算子で厳密な非同値性をテストします。

assert.throws(block, [error], [message])#

block がエラーをスローすることを期待します。 error はコンストラクタ、正規表現、または検証関数にすることができます。

コンストラクタを使って instanceof で検証:

assert.throws(
  function() {
    throw new Error("Wrong value");
  },
  Error
);

正規表現を使ってエラーメッセージを検証:

assert.throws(
  function() {
    throw new Error("Wrong value");
  },
  /value/
);

独自のエラー検証:

assert.throws(
  function() {
    throw new Error("Wrong value");
  },
  function(err) {
    if ( (err instanceof Error) && /value/.test(err) ) {
      return true;
    }
  },
  "unexpected error"
);

assert.doesNotThrow(block, [message])#

block がエラーをスローしないことを期待します。 詳細は assert.throws を参照してください。

assert.ifError(value)#

value が false でないことをテストし、true だったらそれをスローします。 コールバックの第 1 引数である error をテストするのに便利です。

TTY#

Stability: 2 - Unstable

tty モジュールは tty.ReadStreamtty.WriteStream クラスを持ちます。 多くのケースでは、これらを直接使う必要はありません。

node は TTY コンテキストの中にいるかどうかを検出し、 process.stdintty.ReadStream のインスタンスに、 process.stdouttty.WriteStream のインスタンスになります。 もし node が TTY のコンテキストで実行されているかどうかをチェックしたければ、 process.stdout.isTTY を使うことができます:

$ node -p -e "Boolean(process.stdout.isTTY)"
true
$ node -p -e "Boolean(process.stdout.isTTY)" | cat
false

tty.isatty(fd)#

fd が端末に関連づけられているかどうかを true または false で返します。

tty.setRawMode(mode)#

Deprecated. 代わりに tty.ReadStream#setRawMode() (すなわち、process.stdin.setRawMode()) を使用してください。

Class: ReadStream#

net.Socket のサブクラスで、tty の入力側を表現します。 一般的な状況では、どんなプログラムでも (isatty(0) が true の場合に限り) process.stdin が唯一の tty.ReadStream のインスタンスとなります。

rs.isRaw#

Boolean 値で false に初期化されます。 tty.ReadStream インスタンスの現在の "raw" 状態を表現します。

rs.setRawMode(mode)#

modetrue または false のどちらかです。 これは tty.ReadStream がローデバイスかデフォルトのどちらで振る舞うかを 設定します。 結果のモードは isRaw に設定されます。

Class: WriteStream#

net.Socket のサブクラスで、tty の出力側を表現します。 一般的な状況では、どんなプログラムでも (isatty(1) が true の場合に限り) process.stdout が唯一の tty.WriteStream のインスタンスとなります。

ws.columns#

TTY の現在のカラム数を保持する Number 値です。 このプロパティは 'resize' イベントで更新されます。

ws.rows#

TTY の現在の行数を保持する Number 値です。 このプロパティは 'resize' イベントで更新されます。

Event: 'resize'#

function () {}

columns または rows プロパティが変更された場合に refreshSize() によって生成されます。

process.stdout.on('resize', function() {
  console.log('screen size has changed!');
  console.log(process.stdout.columns + 'x' + process.stdout.rows);
});

Zlib#

Stability: 3 - Stable

このモジュールは次のようにアクセスできます。

var zlib = require('zlib');

これは Gzip/Gunzip、Deflate/Inflate、そして DeflateRaw/InflateRaw へバインディングするクラスを提供します。 どのクラスも同じオプションを持つ、読み込みと書き込みが可能なストリームです。

Examples#

ファイルを圧縮および解凍するには、fs.ReadStream から zlib へ、 そして fs.WriteStream へパイプをつなぐだけです。

var gzip = zlib.createGzip();
var fs = require('fs');
var inp = fs.createReadStream('input.txt');
var out = fs.createWriteStream('input.txt.gz');

inp.pipe(gzip).pipe(out);

データの圧縮または解凍は 簡易メソッド を使うことにより、ワンステップで行うことができます。

var input = '.................................';
zlib.deflate(input, function(err, buffer) {
  if (!err) {
    console.log(buffer.toString('base64'));
  }
});

var buffer = new Buffer('eJzT0yMAAGTvBe8=', 'base64');
zlib.unzip(buffer, function(err, buffer) {
  if (!err) {
    console.log(buffer.toString());
  }
});

このモジュールを HTTP クライアントとサーバで使うには、リクエストに accept-encoding ヘッダを、レスポンスに content-encoding ヘッダを使用します。

注意: これらのサンプルは基本コンセプトを見せるためにとても単純化されています。 Zlib エンコーディングは高価なので、結果はキャッシュされるべきです。 zlibの使い方に関する速度/メモリ/圧縮率のトレードオフについてより詳しくは、 後述の Memory Usage Tuning を参照してください。

// client request example
var zlib = require('zlib');
var http = require('http');
var fs = require('fs');
var request = http.get({ host: 'izs.me',
                         path: '/',
                         port: 80,
                         headers: { 'accept-encoding': 'gzip,deflate' } });
request.on('response', function(response) {
  var output = fs.createWriteStream('izs.me_index.html');

  switch (response.headers['content-encoding']) {
    // or, just use zlib.createUnzip() to handle both cases
    case 'gzip':
      response.pipe(zlib.createGunzip()).pipe(output);
      break;
    case 'deflate':
      response.pipe(zlib.createInflate()).pipe(output);
      break;
    default:
      response.pipe(output);
      break;
  }
});

// server example
// Running a gzip operation on every request is quite expensive.
// It would be much more efficient to cache the compressed buffer.
var zlib = require('zlib');
var http = require('http');
var fs = require('fs');
http.createServer(function(request, response) {
  var raw = fs.createReadStream('index.html');
  var acceptEncoding = request.headers['accept-encoding'];
  if (!acceptEncoding) {
    acceptEncoding = '';
  }

  // Note: this is not a conformant accept-encoding parser.
  // See http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.3
  if (acceptEncoding.match(/\bdeflate\b/)) {
    response.writeHead(200, { 'content-encoding': 'deflate' });
    raw.pipe(zlib.createDeflate()).pipe(response);
  } else if (acceptEncoding.match(/\bgzip\b/)) {
    response.writeHead(200, { 'content-encoding': 'gzip' });
    raw.pipe(zlib.createGzip()).pipe(response);
  } else {
    response.writeHead(200, {});
    raw.pipe(response);
  }
}).listen(1337);

zlib.createGzip([options])#

options によって作られた新しい Gzip オブジェクトを返します。

zlib.createGunzip([options])#

options によって作られた新しい Gunzip オブジェクトを返します。

zlib.createDeflate([options])#

options によって作られた新しい Deflate オブジェクトを返します。

zlib.createInflate([options])#

options によって作られた新しい Inflate オブジェクトを返します。

zlib.createDeflateRaw([options])#

options によって作られた新しい DeflateRaw オブジェクトを返します。

zlib.createInflateRaw([options])#

options によって作られた新しい InflateRaw オブジェクトを返します。

zlib.createUnzip([options])#

options によって作られた新しい Unzip オブジェクトを返します。

Class: zlib.Zlib#

zlib モジュールによって公開されてはいません。 ここで文書化するのは圧縮/解凍クラスのベースクラスだからです。

zlib.flush([kind], callback)#

kind のデフォルトは zlib.Z_FULL_FLUSH です。

保留中のデータをフラッシュします。 これを気軽に呼び出さないでください、性急なフラッシュは圧縮アルゴリズムに ネガティブな影響を与えます。

zlib.params(level, strategy, callback)#

圧縮のレベルと戦略を動的に更新します。 deflate アルゴリズムにだけ適用されます。

zlib.reset()#

圧縮/解凍をファクトリのデフォルトにリセットします。 inflate および deflate アルゴリズムにのみ効果があります。

Class: zlib.Gzip#

gzip を使ってデータを圧縮します。

Class: zlib.Gunzip#

gzip ストリームを解凍します。

Class: zlib.Deflate#

deflate を使ってデータを圧縮します。

Class: zlib.Inflate#

deflate ストリームを解凍します。

Class: zlib.DeflateRaw#

deflate を使ってデータを圧縮しますが、zlib ヘッダを付加しません。

Class: zlib.InflateRaw#

生の deflate ストリームを解凍します。

Class: zlib.Unzip#

Gzip または Deflate で圧縮されたストリームをヘッダで自動判別して解凍します。

Convenience Methods#

これらは全て第 1 引数として文字列またはバッファを、 任意の第 2 引数で zlib クラスのオプションを受け取り、 与えられたコールバック callback(error, result) を呼び出します。

zlib.deflate(buf, [options], callback)#

Deflate で文字列を圧縮します。

zlib.deflateRaw(buf, [options], callback)#

DeflateRaw で文字列を圧縮します。

zlib.gzip(buf, [options], callback)#

Gzip で文字列を圧縮します。

zlib.gunzip(buf, [options], callback)#

Gunzip で生のバッファを解凍します。

zlib.inflate(buf, [options], callback)#

Inflate で生のバッファを解凍します。

zlib.inflateRaw(buf, [options], callback)#

InflateRaw で生のバッファを解凍します。

zlib.unzip(buf, [options], callback)#

Unzip で生のバッファを解凍します。

Options#

どのクラスもオプションオブジェクトを受け取ります。 全てのオプションは任意です

いくつかのオプションは圧縮にだけ関連し、 解凍するクラスでは無視されることに注意してください。

  • flush (デフォルト: zlib.Z_NO_FLUSH)
  • chunkSize (デフォルト: 16*1024)
  • windowBits
  • level (圧縮のみ)
  • memLevel (圧縮のみ)
  • strategy (圧縮のみ)
  • dictionary (deflate/inflate のみ、デフォルトは空の辞書です)

これらの詳細は http://zlib.net/manual.html#AdvanceddeflateInit2 および inflateInit2 の説明を参照してください。

Memory Usage Tuning#

node は zlib/zconf.h を変更して使っています:

(1 << (windowBits+2)) +  (1 << (memLevel+9))

すなわち: windowBits = 15 の場合 128K + memLevel = 8 の場合 128K (デフォルト値) に加えて数キロバイトが 小さなオブジェクトのために使われます。

たとえば、デフォルトで要求されるメモリを 256K から 128K へ縮小したければ、 次のオプションを設定します:

{ windowBits: 14, memLevel: 7 }

もちろん、これは圧縮率を悪化します (ただ飯ははありません)。

1 << windowBits

この場合、windowBits=15 (デフォルト値) の場合 32K に加えて数キロバイトが 小さなオブジェクトのために使われます。

これは、デフォルト値 16K の chunkSize で指定されたサイズの内部バッファに加えられます。

zlib の圧縮速度は level の設定で劇的に変化します 高レベルにするとより圧縮できますが、完了までの時間が長くなります。 低レベルにするとあまり圧縮されませんが、高速になります。

一般的に、メモリをより多く使うオプションにすると node が zlib を呼び出す回数が 少なくなることを意味し、 一回の write 操作でより多くのデータを処理できることになります。 これはあスピードに影響するもう一つのファクタで、メモリ使用量を犠牲にします。

Constants#

zlib.h に定義された定数は require('zlib') でも定義されます。 通常の使い方ではこれらを設定する必要はありません。 それが存在することで驚かれないように、これらはドキュメント化されます。 このセクションのほとんどは zlib documentation から直接得ることができます。 より詳細は http://zlib.net/manual.html#Constants を参照してください。

利用可能なフラッシュ値。

  • zlib.Z_NO_FLUSH
  • zlib.Z_PARTIAL_FLUSH
  • zlib.Z_SYNC_FLUSH
  • zlib.Z_FULL_FLUSH
  • zlib.Z_FINISH
  • zlib.Z_BLOCK
  • zlib.Z_TREES

圧縮/解凍関数のリターンコード。 負数はエラー、正数は正常なイベントの特別な場合に使われます。

  • zlib.Z_OK
  • zlib.Z_STREAM_END
  • zlib.Z_NEED_DICT
  • zlib.Z_ERRNO
  • zlib.Z_STREAM_ERROR
  • zlib.Z_DATA_ERROR
  • zlib.Z_MEM_ERROR
  • zlib.Z_BUF_ERROR
  • zlib.Z_VERSION_ERROR

圧縮レベル。

  • zlib.Z_NO_COMPRESSION
  • zlib.Z_BEST_SPEED
  • zlib.Z_BEST_COMPRESSION
  • zlib.Z_DEFAULT_COMPRESSION

圧縮ストラテジ。

  • zlib.Z_FILTERED
  • zlib.Z_HUFFMAN_ONLY
  • zlib.Z_RLE
  • zlib.Z_FIXED
  • zlib.Z_DEFAULT_STRATEGY

data_type フィールドで利用可能な値。

  • zlib.Z_BINARY
  • zlib.Z_TEXT
  • zlib.Z_ASCII
  • zlib.Z_UNKNOWN

deflate の圧縮方法 (このバージョンでは一つだけがサポートされます)。

  • zlib.Z_DEFLATED

zalloc、zfree、opaque の初期化用。

  • zlib.Z_NULL

os#

Stability: 4 - API Frozen
オペレーティングシステムに関連する基本的なユーティリティ関数を提供します。

require('os') によってこのモジュールにアクセスします。

os.tmpdir()#

一時ファイルのためのデフォルトディレクトリを返します。

os.endianness()#

CPU のエンディアン (バイトオーダー) を返します。 あり得る値は "BE" または "LE" です。

os.hostname()#

オペレーティングシステムのホスト名を返します。

os.type()#

オペレーティングシステムの名前を返します。

os.platform()#

プラットフォームのオペレーティングシステムを返します。

os.arch()#

オペレーティングシステムの CPU アーキテクチャを返します。 可能性のある値は "x64""arm"、そして "ia32" です。

os.release()#

オペレーティングシステムのリリースを返します。

os.uptime()#

システムが起動してからの秒数を返します。

os.loadavg()#

1 分、5 分、15 分間のロードアベレージを含んだ配列を返します。

ロードアベレージはオペレーティングシステムによって測定されて小数で表される システム活動の測定値です。経験則として、ロードアベレージは理想的には システムの論理 CPU 数よりも小さくあるべきです。

ロードアベレージはとても Unix 的な概念です; それと完全に対応するものは Windows にはありません。そのため、Windows ではこの関数は常に [0, 0, 0] を返します。

os.totalmem()#

システム全体が使用しているメモリのバイト数を返します。

os.freemem()#

システム全体で空いているメモリのバイト数を返します。

os.cpus()#

インストールされている CPU/ コアごとの情報を含んだオブジェクトの配列を返します。 情報はモデル、スピード (MHz)、そして時間 (CPU/コア が使用した user, nice, sys, idle, irq のミリ秒を含んだオブジェクト) です。

os.cpus の例:

[ { model: 'Intel(R) Core(TM) i7 CPU         860  @ 2.80GHz',
    speed: 2926,
    times:
     { user: 252020,
       nice: 0,
       sys: 30340,
       idle: 1070356870,
       irq: 0 } },
  { model: 'Intel(R) Core(TM) i7 CPU         860  @ 2.80GHz',
    speed: 2926,
    times:
     { user: 306960,
       nice: 0,
       sys: 26980,
       idle: 1071569080,
       irq: 0 } },
  { model: 'Intel(R) Core(TM) i7 CPU         860  @ 2.80GHz',
    speed: 2926,
    times:
     { user: 248450,
       nice: 0,
       sys: 21750,
       idle: 1070919370,
       irq: 0 } },
  { model: 'Intel(R) Core(TM) i7 CPU         860  @ 2.80GHz',
    speed: 2926,
    times:
     { user: 256880,
       nice: 0,
       sys: 19430,
       idle: 1070905480,
       irq: 20 } },
  { model: 'Intel(R) Core(TM) i7 CPU         860  @ 2.80GHz',
    speed: 2926,
    times:
     { user: 511580,
       nice: 20,
       sys: 40900,
       idle: 1070842510,
       irq: 0 } },
  { model: 'Intel(R) Core(TM) i7 CPU         860  @ 2.80GHz',
    speed: 2926,
    times:
     { user: 291660,
       nice: 0,
       sys: 34360,
       idle: 1070888000,
       irq: 10 } },
  { model: 'Intel(R) Core(TM) i7 CPU         860  @ 2.80GHz',
    speed: 2926,
    times:
     { user: 308260,
       nice: 0,
       sys: 55410,
       idle: 1071129970,
       irq: 880 } },
  { model: 'Intel(R) Core(TM) i7 CPU         860  @ 2.80GHz',
    speed: 2926,
    times:
     { user: 266450,
       nice: 1480,
       sys: 34920,
       idle: 1072572010,
       irq: 30 } } ]

os.networkInterfaces()#

ネットワークインタフェースの一覧を取得します。

{ lo:
   [ { address: '127.0.0.1',
       netmask: '255.0.0.0',
       family: 'IPv4',
       mac: '00:00:00:00:00:00',
       internal: true },
     { address: '::1',
       netmask: 'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff',
       family: 'IPv6',
       mac: '00:00:00:00:00:00',
       internal: true } ],
  eth0:
   [ { address: '192.168.1.108',
       netmask: '255.255.255.0',
       family: 'IPv4',
       mac: '01:02:03:0a:0b:0c',
       internal: false },
     { address: 'fe80::a00:27ff:fe4e:66a1',
       netmask: 'ffff:ffff:ffff:ffff::',
       family: 'IPv6',
       mac: '01:02:03:0a:0b:0c',
       internal: false } ] }

os.EOL#

オペレーティングシステムに適した行区切り文字を定義した定数です。

Debugger#

Stability: 3 - Stable

V8は外部プロセスから TCP プロトコル経由で接続可能なデバッガを備えています。 Node にはこのデバッガへのクライアントが組み込まれています。 これを使うには、 debug 引数を指定して Node を起動します。 次のようになります:

% node debug myscript.js
< debugger listening on port 5858
connecting... ok
break in /home/indutny/Code/git/indutny/myscript.js:1
  1 x = 5;
  2 setTimeout(function () {
  3   debugger;
debug>

Node のデバッガクライアントはあらゆるコマンドを完全にサポートしているわけではありませんが、 単純なステップ実行やインスペクションが可能です。 スクリプトのソースコードに debugger; 文を挿入すると、 ブレークポイントが有効になります。

例えば、myscript.js が次のようだとします:

// myscript.js
x = 5;
setTimeout(function () {
  debugger;
  console.log("world");
}, 1000);
console.log("hello");

ひとたびデバッガを実行すると、4行目で中断します。

% node debug myscript.js
< debugger listening on port 5858
connecting... ok
break in /home/indutny/Code/git/indutny/myscript.js:1
  1 x = 5;
  2 setTimeout(function () {
  3   debugger;
debug> cont
< hello
break in /home/indutny/Code/git/indutny/myscript.js:3
  1 x = 5;
  2 setTimeout(function () {
  3   debugger;
  4   console.log("world");
  5 }, 1000);
debug> next
break in /home/indutny/Code/git/indutny/myscript.js:4
  2 setTimeout(function () {
  3   debugger;
  4   console.log("world");
  5 }, 1000);
  6 console.log("hello");
debug> repl
Press Ctrl + C to leave debug repl
> x
5
> 2+2
4
debug> next
< world
break in /home/indutny/Code/git/indutny/myscript.js:5
  3   debugger;
  4   console.log("world");
  5 }, 1000);
  6 console.log("hello");
  7
debug> quit
%

repl コマンドはコードをリモートで評価します。 next コマンドは次の行にステップオーバーします。 他にもいくつかのコマンドを利用することができます。 その他については help をタイプしてください。

Watchers#

デバッグ中に式や変数の値をウォッチすることができます。 全てのブレークポイントにおいて、ウォッチリストのそれぞれの式は 現在のコンテキストで評価され、ブレークポイントのソースコードの前に 表示されます。

式のウォッチを開始するには、watch("my_expression") をタイプします。 watchers はアクティブなウォッチの一覧を表示します。 ウォッチを解除するには、unwatch("my_expression") とタイプします。

Commands reference#

Stepping#

  • cont, c - 実行を継続します。
  • next, n - 次の行へステップオーバーします。
  • step, s - ステップインします。
  • out, o - ステップアウトします。
  • pause - コードの実行を中断します (Developer Tools の pause ボタンと同じです。

Breakpoints#

  • setBreakpoint(), sb() - 現在行にブレークポイントを設定します。
  • setBreakpoint(line), sb(line) - 指定した行にブレークポイントを設定します。
  • setBreakpoint('fn()'), sb(...) - 指定した関数の先頭行にブレークポイントを設定します
  • setBreakpoint('script.js', 1), sb(...) - 指定したスクリプトファイルの指定した行にブレークポイントを設定します。
  • clearBreakpoint, cb(...) - ブレークポイントを削除します。

まだロードされていないファイル (モジュール) にブレークポイントを 設定することもできます。

% ./node debug test/fixtures/break-in-module/main.js
< debugger listening on port 5858
connecting to port 5858... ok
break in test/fixtures/break-in-module/main.js:1
  1 var mod = require('./mod.js');
  2 mod.hello();
  3 mod.hello();
debug> setBreakpoint('mod.js', 23)
Warning: script 'mod.js' was not loaded yet.
  1 var mod = require('./mod.js');
  2 mod.hello();
  3 mod.hello();
debug> c
break in test/fixtures/break-in-module/mod.js:23
 21
 22 exports.hello = function() {
 23   return 'hello from module';
 24 };
 25
debug>

Info#

  • backtrace, bt - 現在の実行フレームのバックトレースを表示します。
  • list(5) - 現在の行の前後のソースコードを表示します (例では前後とも 5 行が表示されます)。
  • watch(expr) - 式をウォッチリストに追加します。
  • unwatch(expr) - 式をウォッチリストから削除します。
  • watchers - ウォッチしている全ての式とその値を表示します (各ブレークポイントで自動的に表示されます)。
  • repl - デバッグしているスクリプトをコンテキストとする REPL を開きます。

Execution control#

  • run - スクリプトを実行します (デバッガを開始すると自動的に実行します)。
  • restart - スクリプトを再実行します。
  • kill - スクリプトを終了します。

Various#

  • scripts - ロードされている全スクリプトの一覧を表示します。
  • version - v8 のバージョンを表示します。

Advanced Usage#

V8 デバッガは Node をコマンドラインの --debug フラグで起動したり、起動済みの Node プロセスに SIGUSR1 シグナルを送ることでも有効にできます。

これによって一度デバッグモードに設定されたプロセスは、 pid または URI のどちらでも node デバッガに接続することができます。 形式は:

  • node debug -p <pid> - pid を通じてプロセスに接続
  • node debug <URI> - localhost:585 のような URI を通じてプロセスに接続

Cluster#

Stability: 2 - Unstable

一つの Node インスタンスは一つのスレッドで実行されます。 マルチコアシステムのメリットを生かすために、 ユーザは時々 Node プロセスのクラスを起動して負荷を分散したくなります。

クラスタモジュールは、サーバポートを共有する複数の子プロセスを簡単に 構築することを可能にします。

var cluster = require('cluster');
var http = require('http');
var numCPUs = require('os').cpus().length;

if (cluster.isMaster) {
  // Fork workers.
  for (var i = 0; i < numCPUs; i++) {
    cluster.fork();
  }

  cluster.on('exit', function(worker, code, signal) {
    console.log('worker ' + worker.process.pid + ' died');
  });
} else {
  // Workers can share any TCP connection
  // In this case its a HTTP server
  http.createServer(function(req, res) {
    res.writeHead(200);
    res.end("hello world\n");
  }).listen(8000);
}

node は 8000 番ポートをワーカ間で共有します。

% NODE_DEBUG=cluster node server.js
23521,Master Worker 23524 online
23521,Master Worker 23526 online
23521,Master Worker 23523 online
23521,Master Worker 23528 online

この機能は最近導入されたばかりであり、 将来のバージョンで変更される可能性があります。 これを試して、フィードバックを行ってください。

Windows では、ワーカが名前付きパイプによるサーバをセットアップすることは まだできないことにも注意してください。

How It Works#

ワーカプロセスは child_process.fork メソッドを使って起動されるため、 親プロセスと IPC で通信したり、サーバハンドルをやり取りしたりすることが できます。

クラスタモジュールは到着する接続を分散する方法を二種類提供します。

一つ目 (Windows 以外の全てのプラットフォームでデフォルト) はラウンドロビン方式で、マスタプロセスがポートをリッスンし、 新しい接続を受け付けるとラウンドロビン方式でワーカに分散します (ワーカの過負荷を避ける工夫が組み込まれています)。

二つ目の方法は、マスタプロセスがリスニングソケットを作成し、 ワーカに送信します。ワーカは到着する接続を直接受け付けます。

二つ目の方法は、原則的には、ベストなパフォーマンスであるべきです。 しかし実際には、OS の予測不可能なスケジューラにより、 非常に不均衡に分散される傾向があります。 全 8 プロセス中の 2 プロセスに 70% 以上の接続が割り当てられたことも 観測されました。

server.listen() は仕事の大部分をマスタプロセスに渡すため、 通常の node.js プロセスとクラスタのワーカプロセスの間には 振る舞いが異なるケースが 3 つあります。

  1. server.listen({fd: 7}) メッセージはマスタに渡されてるため、 ワーカのファイル記述子 7 が参照するものではなく、 親プロセスの ファイル記述子 7 がリスニングされてそのハンドルがワーカに 渡されます。
  2. server.listen(handle) 明示的なハンドルをリスニングするとマスタプロセスは 関与することなく、ワーカは与えられたハンドルを使うことになります。 ワーカがすでにハンドルを持っているなら、何をしようとしているか あなたは分かっているでしょう。
  3. 'server.listen(0) 通常、これはサーバがランダムなポートをリッスンすることを 意味します。しかしながらクラスタでは、各ワーカは listen(0) によって 同じ "ランダムな" ポートを受信します。 すなわち、初回はポートはランダムになりますが、その後はそうではありません。 もしユニークなポートをリッスンしたければ、クラスタのワーカ ID に基づいて ポート番号を生成してください。

Node.js にもあなたのプログラムにも、ルーティングのためのロジックや ワーカ間で共有される状態はありません。 したがって、あなたのプログラムがセッションやログインのためにメモリ内の データオブジェクトに過度に頼らないように設計することが重要です。

全てのワーカは独立したプロセスなので、他のワーカに影響を与えることなく プログラムのニーズに応じてそれらを殺したり再起動したりすることができます。 いくつかのワーカが生きている限り、サーバは接続を受け付け続けます。 しかしながら、Node はワーカの数を自動的に管理することはありません。 アプリケーションのニーズに応じてワーカのプールを管理することは、 あなたの責務です。

cluster.schedulingPolicy#

スケジューリングポリシーは、ラウンドロビンの cluster.SCHED_RR または、 OS に任せる cluster.SCHED_NONE のどちらかです。 これはグローバルな設定で、その効果は最初のワーカを起動する時か、 cluster.setupMaster() を呼び出した時、どちらかが最初に行われた時点で 凍結されます。

SCHED_RR は Windows 以外の全ての OS でデフォルトです。 Windows では、libuv が大きなパフォーマンス低下を招くことなく IOCP ハンドルを分散することが可能であれば、SCHED_RR に切り替わります。

cluster.schedulingPolicy は、NODE_CLUSTER_SCHED_POLICY 環境変数を 通じて設定することもできます。適切な値は "rr" または "none" です。

cluster.settings#

  • {Object}
    • execArgv {Array} node 実行ファイルに渡される引数を表す、文字列の配列 (デフォルトは process.execArgv)。
    • exec {String} ワーカで実行するファイルへのパス (デフォルトは process.argv[1])。
    • args {Array} ワーカに渡される引数となる文字列 (デフォルトは process.argv.slice(2))。
    • silent {Boolean} 出力を親プロセスに送るかどうか (デフォルトは false)。

.setupMaster() (または .fork()) が呼び出された後、この settings オブジェクトはデフォルト値を含む設定オブジェクトを持ちます。

.setupMaster() は一度しか呼び出せないため、それは設定された後で事実上 凍結されます。

このオブジェクトはあなたによって変更されることを想定していません。

cluster.isMaster#

  • Boolean

現在のプロセスがマスタの場合は true です。 これは process.env.NODE_UNIQUE_ID から決定されます。 process.env.NODE_UNIQUE_ID が未定義だと isMastertrue になります。

cluster.isWorker#

  • Boolean

このプロセスがマスタでなければ true (これは cluster.isMaster の否定です)。

Event: 'fork'#

  • worker Worker object

新しいワーカがフォークされると、クラスタモジュールは 'fork' イベントを 生成します。 これはワーカの活動をロギングしたり、タイムアウトのために使うことができます。

var timeouts = [];
function errorMsg() {
  console.error("Something must be wrong with the connection ...");
}

cluster.on('fork', function(worker) {
  timeouts[worker.id] = setTimeout(errorMsg, 2000);
});
cluster.on('listening', function(worker, address) {
  clearTimeout(timeouts[worker.id]);
});
cluster.on('exit', function(worker, code, signal) {
  clearTimeout(timeouts[worker.id]);
  errorMsg();
});

Event: 'online'#

  • worker Worker object

新しいワーカをフォークした後、ワーカはオンラインメッセージを応答します。 マスタがオンラインメッセージを受信すると、このイベントが生成されます。 'fork''online' の違いは、'fork' はマスタがワーカをフォークした時点で 生成されるのに対し、'online' はワーカが実行されてから生成される点です。

cluster.on('online', function(worker) {
  console.log("Yay, the worker responded after it was forked");
});

Event: 'listening'#

  • worker Worker object
  • address Object

ワーカが net.Server.listen() を呼び出した後、(net や http などの) サーバでは 'listening' イベントが生成され、マスタの cluster でも 'listening' イベントが生成されます。

イベントハンドラは二つの引数を伴って実行されます。 worker はワーカオブジェクトを、address オブジェクトは 以下の接続プロパティを含みます: addressprot、そして addressType です。 これはワーカが複数のアドレスをリッスンしている場合にとても便利です。

cluster.on('listening', function(worker, address) {
  console.log("A worker is now connected to " + address.address + ":" + address.port);
});

addressType は以下のいずれかです:

  • 4 (TCPv4)
  • 6 (TCPv6)
  • -1 (unix ドメインソケット)
  • "udp4" または "udp6" (UDP v4 または v6)

Event: 'disconnect'#

  • worker Worker object

ワーカとの IPC チャネルが切断された後で生成されます。 それはワーカが自然に終了したり、殺されたり、あるいは (worker.disconnect() により) 手動で切断された場合に発生します。

'disconnect''exit' の間には遅延があるかもしれません。 このイベントはプロセスがクリーンナップで行き詰まったり、長時間生きている接続が ないかを検出することに使用できます。

cluster.on('disconnect', function(worker) {
  console.log('The worker #' + worker.id + ' has disconnected');
});

Event: 'exit'#

  • worker {Worker object}
  • code {Number} 正常に終了した場合は終了コード。
  • signal {String} プロセスが殺される原因となったシグナルの名前 (例: 'SIGHUP')。

どのワーカが死んだ場合でも、クラスタモジュールは 'exit' イベントを 生成します。

これは .fork() を呼び出してワーカを再開する場合に使用することができます。

cluster.on('exit', function(worker, code, signal) {
  console.log('worker %d died (%s). restarting...',
    worker.process.pid, signal || code);
  cluster.fork();
});

See child_process event: 'exit'.

Event: 'setup'#

setupMaster() が最初に呼ばれた時に生成されます。

cluster.setupMaster([settings])#

  • settings {Object}
    • exec {String} ワーカで実行するファイルへのパス. (デフォルトは process.argv[1])
    • args {Array} ワーカに渡される引数となる文字列。 (デフォルトは process.argv.slice(2))
    • silent {Boolean} 出力を親プロセスに送るかどうか。 (デフォルトは false)

setupMaster() は 'fork' のデフォルト動作を変更するために使われます。 一度呼び出されると、その設定は cluster.settings に反映されます。

注意事項:

  • .setupMaster() の最初の呼び出しだけ効果があります。 その後の呼び出しは無視されます。
  • 上記のため、ワーカごとにカスタマイズできる属性は .fork() に渡すことのできる env だけ です。
  • .fork() はデフォルト値を反映するために内部で .setupMaster() を呼び出すため、.setupMaster() が効果を持つには .fork() よりも前に 呼び出す必要があります。

例:

var cluster = require("cluster");
cluster.setupMaster({
  exec : "worker.js",
  args : ["--use", "https"],
  silent : true
});
cluster.fork();

これはマスタプロセスからのみ、呼び出すことができます。

cluster.fork([env])#

  • env {Object} ワーカプロセスの環境に加えられるキーと値のペア。
  • return {Worker object}

新しいワーカプロセスを起動します。

これはマスタプロセスからのみ呼び出すことができます。

cluster.disconnect([callback])#

  • callback {Function} 全てのワーカが切断し、ハンドルがクローズされると 呼び出されます。

cluster.workers 内の各ワーカに対して .disconnect() を呼び出します。

ワーカとの接続が切断して内部的なハンドルが全てクローズされると、 他に待機しているイベントがなければ、マスタプロセスは自然に終了します。

このメソッドはオプションの引数としてコールバックを受け取ります。

これはマスタプロセスからのみ呼び出すことができます。

cluster.worker#

  • Object

現在のワーカオブジェクトへの参照です。 マスタプロセスでは利用できません。

var cluster = require('cluster');

if (cluster.isMaster) {
  console.log('I am master');
  cluster.fork();
  cluster.fork();
} else if (cluster.isWorker) {
  console.log('I am worker #' + cluster.worker.id);
}

cluster.workers#

  • Object

id をキーとしてアクティブなワーカオブジェクトを保存しているハッシュです。 これは全てのワーカに対して繰り返しを行うことを容易にします。 マスタプロセスでのみ利用可能です。

ワーカは 'disconnect''exit' が生成される前に cluster.worker から 削除されます。

// Go through all workers
function eachWorker(callback) {
  for (var id in cluster.workers) {
    callback(cluster.workers[id]);
  }
}
eachWorker(function(worker) {
  worker.send('big announcement to all workers');
});

通信チャネルを越えてワーカの参照を渡す場合は、 ワーカのユニークな ID を使ってワーカを探すのが簡単です。

socket.on('data', function(id) {
  var worker = cluster.workers[id];
});

Class: Worker#

ワーカに関する全ての公開された情報やメソッドを持つオブジェクトです。 マスタでは cluster.wrokers から取得することができます。 ワーカでは cluster.worker から取得することができます。

worker.id#

  • String

新しいワーカはいずれもユニークな ID を与えられます。 この ID は id に保存されます。

ワーカが生きている間、これは cluseter.workers のキーとなります。

worker.process#

  • ChildProcess object

全てのワーカは child_process.fork() によって作成されます。 その戻り値は .process に設定されます。 ワーカでは、グローバルの process に設定されます。

参照: Child Process module

process'disconnect' イベントが生成されるとワーカが process.exit(0) を呼び出し、.suicidetrue にならないことに注意してください。 これは偶発的な切断を防ぎます。

worker.suicide#

  • Boolean

.kill() または .disconnect() によって設定されます。 それまでは undefined です。

真偽値の worker.suicide は、ワーカが自発的に終了したのか偶発的に終了したのかを 区別します。 マスタはこの値に基づいて、ワーカを再起動しないことを選ぶことができます。

cluster.on('exit', function(worker, code, signal) {
  if (worker.suicide === true) {
    console.log('Oh, it was just suicide\' – no need to worry').
  }
});

// kill worker
worker.kill();

worker.send(message, [sendHandle])#

  • message Object
  • sendHandle Handle object

この関数は child_process.fork() が返すオブジェクトの send() メソッドと同じです。 マスタは特定のワーカにメッセージを送信するためにこの関数を 使用することができます。

ワーカでは process.send(message) を使うこともできます。 それは同じ関数です。

この例はマスタからのメッセージをエコーバックします。

if (cluster.isMaster) {
  var worker = cluster.fork();
  worker.send('hi there');

} else if (cluster.isWorker) {
  process.on('message', function(msg) {
    process.send(msg);
  });
}

worker.kill([signal='SIGTERM'])#

  • signal {String} ワーカプロセスに送られるシグナルの名前です。

この関数はワーカを終了します。 マスタでは、これは worker.process と切断することによって行われます。 そして切断されると、signal によってワーカを殺します。 ワーカでは、これはチャネルの切断によって行われ、コード 0 で終了します。

.suicide が設定される原因となります。

後方互換性のため、このメソッドには worker.destroy() という別名があります。

ワーカでは、process.kill() は存在するものの、それは関数ではないことに 注意してください。 kill を参照してください。

worker.disconnect()#

ワーカでは、この関数は全てのサーバをクローズし、それらのサーバの 'close' イベントを待機し、そして IPC チャネルを切断します。

マスタでは、ワーカが自分の .disconnect() を呼び出すことになる内部メッセージを ワーカに送ります。

.suicide が設定される原因となります。

サーバがクローズした後、それはもう新たな接続を受け付けなくなりますが、 他のワーカによって接続は受け付けられることに注意してください。 既存のコネクションは通常通りクローズすることができます。 コネクションが無くなると (server.close() 参照)、 ワーカが自然に終了できるように IPC チャネルはクローズされます。

上記はサーバ側のコネクションにのみ適用されます。 クライアント側のコネクションはワーカによって自動的にクローズされることはなく、 終了する前にそれらがクローズすることを待つこともありません。

ワーカでは、process.disconnect は存在しますが、それはここで説明した関数では ありません。それは disconnect です。

長時間生きているサーバ側のコネクションはワーカが切断することを妨げるため、 それらをクローズするためにアプリケーション固有のメッセージを送ることは有用です。 加えて、一定の時間が経過しても 'disconnect' イベントが発生しなかった場合に ワーカを強制終了する実装も有用です。

if (cluster.isMaster) {
  var worker = cluster.fork();
  var timeout;

  worker.on('listening', function(address) {
    worker.send('shutdown');
    worker.disconnect();
    timeout = setTimeout(function() {
      worker.kill();
    }, 2000);
  });

  worker.on('disconnect', function() {
    clearTimeout(timeout);
  });

} else if (cluster.isWorker) {
  var net = require('net');
  var server = net.createServer(function(socket) {
    // connections never end
  });

  server.listen(8000);

  process.on('message', function(msg) {
    if(msg === 'shutdown') {
      // initiate graceful close of any connections to server
    }
  });
}

Event: 'message'#

  • message Object

このイベントは child_process.fork() が提供するものと同じです。

ワーカでは、process.on('message') を使うこともできます。

メッセージシステムを使用してクラスタ全体のリクエスト数を マスタプロセスで保持する例です:

var cluster = require('cluster');
var http = require('http');

if (cluster.isMaster) {

  // Keep track of http requests
  var numReqs = 0;
  setInterval(function() {
    console.log("numReqs =", numReqs);
  }, 1000);

  // Count requestes
  function messageHandler(msg) {
    if (msg.cmd && msg.cmd == 'notifyRequest') {
      numReqs += 1;
    }
  }

  // Start workers and listen for messages containing notifyRequest
  var numCPUs = require('os').cpus().length;
  for (var i = 0; i < numCPUs; i++) {
    cluster.fork();
  }

  Object.keys(cluster.workers).forEach(function(id) {
    cluster.workers[id].on('message', messageHandler);
  });

} else {

  // Worker processes have a http server.
  http.Server(function(req, res) {
    res.writeHead(200);
    res.end("hello world\n");

    // notify master about the request
    process.send({ cmd: 'notifyRequest' });
  }).listen(8000);
}

Event: 'online'#

cluster.on('online') と同様ですが、このワーカに特化しています。

cluster.fork().on('online', function() {
  // Worker is online
});

このイベントはワーカでは生成されません。

Event: 'listening'#

  • address Object

cluster.on('listening') と同様ですが、このワーカに特化しています。

cluster.fork().on('listening', function(address) {
  // Worker is listening
});

このイベントはワーカでは生成されません。

Event: 'disconnect'#

cluster.on('disconnect') と同様ですが、このワーカに特化しています。

cluster.fork().on('disconnect', function() {
  // Worker has disconnected
});

Event: 'exit'#

  • code {Number} 正常に終了した場合は終了コード。
  • signal {String} プロセスが殺される原因となったシグナルの名前 (例: 'SIGHUP')。

cluster.on('exit') と同様ですが、このワーカに特化しています。

var worker = cluster.fork();
worker.on('exit', function(code, signal) {
  if( signal ) {
    console.log("worker was killed by signal: "+signal);
  } else if( code !== 0 ) {
    console.log("worker exited with error code: "+code);
  } else {
    console.log("worker success!");
  }
});

Event: 'error'#

このイベントは child_process.fork() が提供するものと同じです。

ワーカでは process.on('error') を使うこともできます。

Smalloc#

Stability: 1 - Experimental

smalloc.alloc(length[, receiver][, type])#

  • length {Number} <= smalloc.kMaxLength
  • receiver {Object} オプション、デフォルトは new Object
  • type {Enum} オプション、デフォルトは Uint8

外部の配列データが割り当てられた receiver を返します。 receiver が渡されなかった場合は新しいオブジェクトが作成されて返されます。

バッファは、外部の生のメモリを割り当てるだけの単純なアロケータに 支えられています。Smallocはその機能を公開します。

これはバッファのような独自クラスの作成に用いることができます。 他のどんなプロパティも設定されないので、利用者は必要な情報 (例えば割り当てた長さの length) を追跡できるようにする必要があります。

function SimpleData(n) {
  this.length = n;
  smalloc.alloc(this.length, this);
}

SimpleData.prototype = { /* ... */ };

receiver は配列以外のオブジェクトであることがチェックされるだけです。 このため、外部の配列データをプレーンなオブジェクト以上のものに 割り当てることができます。

function allocMe() { }
smalloc.alloc(3, allocMe);

// { [Function allocMe] '0': 0, '1': 0, '2': 0 }

v8は外部の配列データを Array オブジェクトに割り当てることを サポートしていないため、もし渡すと例外がスローされます。

外部の配列データの型を指定することができます。 全ての可能なオプションは smalloc.Types に列挙されています。使用例:

var doubleArr = smalloc.alloc(3, smalloc.Types.Double);

for (var i = 0; i < 3; i++)
  doubleArr = i / 10;

// { '0': 0, '1': 0.1, '2': 0.2 }

smalloc.copyOnto(source, sourceStart, dest, destStart, copyLength);#

  • source 外部の配列が割り当てられたオブジェクト
  • sourceStart コピーを開始する位置
  • dest 外部の配列が割り当てられたオブジェクト
  • destStart コピーを開始する位置
  • copyLength コピーする長さ

外部の配列に割り当てられたメモリの一つから別のメモリへコピーします。 全ての引数は必須で、どんな違反でも例外がスローされます。

var a = smalloc.alloc(4);
var b = smalloc.alloc(4);

for (var i = 0; i < 4; i++) {
  a[i] = i;
  b[i] = i * 2;
}

// { '0': 0, '1': 1, '2': 2, '3': 3 }
// { '0': 0, '1': 2, '2': 4, '3': 6 }

smalloc.copyOnto(b, 2, a, 0, 2);

// { '0': 4, '1': 6, '2': 2, '3': 3 }

copyOnto() は内部で割り当てられた長さを自動的に検出するので、 これが動作するために追加のプロパティを設定する必要はありません。

smalloc.dispose(obj)#

  • obj Object

smalloc.alloc() によってオブジェクトに割り当てられたメモリを解放します。

var a = {};
smalloc.alloc(3, a);

// { '0': 0, '1': 0, '2': 0 }

smalloc.dispose(a);

// {}

これはガーベッジコレクションの負荷を軽減しますが、開発者は注意が必要です。 不可解なエラーが追跡の難しいアプリケーションで発生するかもしれません。

var a = smalloc.alloc(4);
var b = smalloc.alloc(4);

// perform this somewhere along the line
smalloc.dispose(b);

// now trying to copy some data out
smalloc.copyOnto(b, 2, a, 0, 2);

// now results in:
// Error: source has no external array data

dispose()Buffer をサポートしません。もし渡されると例外をスローします。

smalloc.hasExternalData(obj)#

  • obj Object

obj が外部に割り当てられたメモリを持つなら true を返します。

smalloc.kMaxLength#

割り当てられる最大長です。 これは Buffer を作成する際にも適用されます。

smalloc.Types#

外部の配列で可能な型の列挙です。以下を含みます:

  • Int8
  • Uint8
  • Int16
  • Uint16
  • Int32
  • Uint32
  • Float
  • Double
  • Uint8Clamped