Node.js v0.11.11 マニュアル & ドキュメンテーション
Table of Contents
- About this Documentation
- Synopsis
- Global Objects
- console
- Timers
- Modules
- Addons
- process
- Exit Codes
- Event: 'exit'
- Event: 'uncaughtException'
- Signal Events
- process.stdout
- process.stderr
- process.stdin
- process.argv
- process.execPath
- process.execArgv
- process.abort()
- process.chdir(directory)
- process.cwd()
- process.env
- process.exit([code])
- process.exitCode
- process.getgid()
- process.setgid(id)
- process.getuid()
- process.setuid(id)
- process.getgroups()
- process.setgroups(groups)
- process.initgroups(user, extra_group)
- process.version
- process.versions
- process.config
- process.kill(pid, [signal])
- process.pid
- process.title
- process.arch
- process.platform
- process.memoryUsage()
- process.nextTick(callback)
- process.umask([mask])
- process.uptime()
- process.hrtime()
- Async Listeners
- process.createAsyncListener(callbacksObj[, userData])
- process.addAsyncListener(callbacksObj[, userData])
- process.addAsyncListener(asyncListener)
- process.removeAsyncListener(asyncListener)
- util
- util.debuglog(section)
- util.format(format, [...])
- util.log(string)
- util.inspect(object, [options])
- util.isArray(object)
- util.isRegExp(object)
- util.isDate(object)
- util.isError(object)
- util.inherits(constructor, superConstructor)
- util.debug(string)
- util.error([...])
- util.puts([...])
- util.print([...])
- util.pump(readableStream, writableStream, [callback])
- Events
- Class: events.EventEmitter
- emitter.addListener(event, listener)
- emitter.on(event, listener)
- emitter.once(event, listener)
- emitter.removeListener(event, listener)
- emitter.removeAllListeners([event])
- emitter.setMaxListeners(n)
- EventEmitter.defaultMaxListeners
- emitter.listeners(event)
- emitter.emit(event, [arg1], [arg2], [...])
- Class Method: EventEmitter.listenerCount(emitter, event)
- Event: 'newListener'
- Event: 'removeListener'
- Class: events.EventEmitter
- Domain
- Buffer
- Class: Buffer
- new Buffer(size)
- new Buffer(array)
- new Buffer(str, [encoding])
- Class Method: Buffer.isEncoding(encoding)
- Class Method: Buffer.isBuffer(obj)
- Class Method: Buffer.byteLength(string, [encoding])
- Class Method: Buffer.concat(list, [totalLength])
- buf.length
- buf.write(string, [offset], [length], [encoding])
- buf.toString([encoding], [start], [end])
- buf.toJSON()
- buf[index]
- buf.copy(targetBuffer, [targetStart], [sourceStart], [sourceEnd])
- buf.slice([start], [end])
- buf.readUInt8(offset, [noAssert])
- buf.readUInt16LE(offset, [noAssert])
- buf.readUInt16BE(offset, [noAssert])
- buf.readUInt32LE(offset, [noAssert])
- buf.readUInt32BE(offset, [noAssert])
- buf.readInt8(offset, [noAssert])
- buf.readInt16LE(offset, [noAssert])
- buf.readInt16BE(offset, [noAssert])
- buf.readInt32LE(offset, [noAssert])
- buf.readInt32BE(offset, [noAssert])
- buf.readFloatLE(offset, [noAssert])
- buf.readFloatBE(offset, [noAssert])
- buf.readDoubleLE(offset, [noAssert])
- buf.readDoubleBE(offset, [noAssert])
- buf.writeUInt8(value, offset, [noAssert])
- buf.writeUInt16LE(value, offset, [noAssert])
- buf.writeUInt16BE(value, offset, [noAssert])
- buf.writeUInt32LE(value, offset, [noAssert])
- buf.writeUInt32BE(value, offset, [noAssert])
- buf.writeInt8(value, offset, [noAssert])
- buf.writeInt16LE(value, offset, [noAssert])
- buf.writeInt16BE(value, offset, [noAssert])
- buf.writeInt32LE(value, offset, [noAssert])
- buf.writeInt32BE(value, offset, [noAssert])
- buf.writeFloatLE(value, offset, [noAssert])
- buf.writeFloatBE(value, offset, [noAssert])
- buf.writeDoubleLE(value, offset, [noAssert])
- buf.writeDoubleBE(value, offset, [noAssert])
- buf.fill(value, [offset], [end])
- buf.toArrayBuffer()
- buffer.INSPECT_MAX_BYTES
- Class: SlowBuffer
- Class: Buffer
- Stream
- API for Stream Consumers
- API for Stream Implementors
- Streams: Under the Hood
- Crypto
- crypto.setEngine(engine, [flags])
- crypto.getCiphers()
- crypto.getHashes()
- crypto.createCredentials(details)
- crypto.createHash(algorithm)
- Class: Hash
- crypto.createHmac(algorithm, key)
- Class: Hmac
- crypto.createCipher(algorithm, password)
- crypto.createCipheriv(algorithm, key, iv)
- Class: Cipher
- crypto.createDecipher(algorithm, password)
- crypto.createDecipheriv(algorithm, key, iv)
- Class: Decipher
- crypto.createSign(algorithm)
- Class: Sign
- crypto.createVerify(algorithm)
- Class: Verify
- crypto.createDiffieHellman(prime_length)
- crypto.createDiffieHellman(prime, [encoding])
- Class: DiffieHellman
- diffieHellman.generateKeys([encoding])
- diffieHellman.computeSecret(other_public_key, [input_encoding], [output_encoding])
- diffieHellman.getPrime([encoding])
- diffieHellman.getGenerator([encoding])
- diffieHellman.getPublicKey([encoding])
- diffieHellman.getPrivateKey([encoding])
- diffieHellman.setPublicKey(public_key, [encoding])
- diffieHellman.setPrivateKey(private_key, [encoding])
- crypto.getDiffieHellman(group_name)
- crypto.pbkdf2(password, salt, iterations, keylen, [digest], callback)
- crypto.pbkdf2Sync(password, salt, iterations, keylen, [digest])
- crypto.randomBytes(size, [callback])
- crypto.pseudoRandomBytes(size, [callback])
- Class: Certificate
- crypto.DEFAULT_ENCODING
- Recent API Changes
- TLS (SSL)
- Client-initiated renegotiation attack mitigation
- NPN and SNI
- Perfect Forward Secrecy
- tls.getCiphers()
- tls.createServer(options, [secureConnectionListener])
- tls.connect(options, [callback])
- tls.connect(port, [host], [options], [callback])
- Class: tls.TLSSocket
- new tls.TLSSocket(socket, options)
- tls.createSecurePair([credentials], [isServer], [requestCert], [rejectUnauthorized])
- Class: SecurePair
- Class: tls.Server
- Class: CryptoStream
- Class: tls.TLSSocket
- Event: 'secureConnect'
- tlsSocket.encrypted
- tlsSocket.authorized
- tlsSocket.authorizationError
- tlsSocket.getPeerCertificate()
- tlsSocket.getCipher()
- tlsSocket.renegotiate(options, callback)
- tlsSocket.setMaxSendFragment(size)
- tlsSocket.address()
- tlsSocket.remoteAddress
- tlsSocket.remotePort
- tlsSocket.localAddress
- tlsSocket.localPort
- StringDecoder
- File System
- fs.rename(oldPath, newPath, callback)
- fs.renameSync(oldPath, newPath)
- fs.ftruncate(fd, len, callback)
- fs.ftruncateSync(fd, len)
- fs.truncate(path, len, callback)
- fs.truncateSync(path, len)
- fs.chown(path, uid, gid, callback)
- fs.chownSync(path, uid, gid)
- fs.fchown(fd, uid, gid, callback)
- fs.fchownSync(fd, uid, gid)
- fs.lchown(path, uid, gid, callback)
- fs.lchownSync(path, uid, gid)
- fs.chmod(path, mode, callback)
- fs.chmodSync(path, mode)
- fs.fchmod(fd, mode, callback)
- fs.fchmodSync(fd, mode)
- fs.lchmod(path, mode, callback)
- fs.lchmodSync(path, mode)
- fs.stat(path, callback)
- fs.lstat(path, callback)
- fs.fstat(fd, callback)
- fs.statSync(path)
- fs.lstatSync(path)
- fs.fstatSync(fd)
- fs.link(srcpath, dstpath, callback)
- fs.linkSync(srcpath, dstpath)
- fs.symlink(srcpath, dstpath, [type], callback)
- fs.symlinkSync(srcpath, dstpath, [type])
- fs.readlink(path, callback)
- fs.readlinkSync(path)
- fs.realpath(path, [cache], callback)
- fs.realpathSync(path, [cache])
- fs.unlink(path, callback)
- fs.unlinkSync(path)
- fs.rmdir(path, callback)
- fs.rmdirSync(path)
- fs.mkdir(path, [mode], callback)
- fs.mkdirSync(path, [mode])
- fs.readdir(path, callback)
- fs.readdirSync(path)
- fs.close(fd, callback)
- fs.closeSync(fd)
- fs.open(path, flags, [mode], callback)
- fs.openSync(path, flags, [mode])
- 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)
- fs.fsyncSync(fd)
- fs.write(fd, buffer, offset, length[, position], callback)
- fs.write(fd, data[, position[, encoding]], callback)
- fs.writeSync(fd, buffer, offset, length[, position])
- fs.writeSync(fd, data[, position[, encoding]])
- fs.read(fd, buffer, offset, length, position, callback)
- fs.readSync(fd, buffer, offset, length, position)
- fs.readFile(filename, [options], callback)
- fs.readFileSync(filename, [options])
- fs.writeFile(filename, data, [options], callback)
- fs.writeFileSync(filename, data, [options])
- fs.appendFile(filename, data, [options], callback)
- fs.appendFileSync(filename, data, [options])
- fs.watchFile(filename, [options], listener)
- fs.unwatchFile(filename, [listener])
- fs.watch(filename, [options], [listener])
- fs.exists(path, callback)
- fs.existsSync(path)
- Class: fs.Stats
- fs.createReadStream(path, [options])
- Class: fs.ReadStream
- fs.createWriteStream(path, [options])
- Class: fs.WriteStream
- Class: fs.FSWatcher
- Path
- net
- net.createServer([options], [connectionListener])
- net.connect(options, [connectionListener])
- net.createConnection(options, [connectionListener])
- net.connect(port, [host], [connectListener])
- net.createConnection(port, [host], [connectListener])
- net.connect(path, [connectListener])
- net.createConnection(path, [connectListener])
- Class: net.Server
- server.listen(port, [host], [backlog], [callback])
- server.listen(path, [callback])
- server.listen(handle, [callback])
- server.close([callback])
- server.address()
- server.unref()
- server.ref()
- server.maxConnections
- server.connections
- server.getConnections(callback)
- Event: 'listening'
- Event: 'connection'
- Event: 'close'
- Event: 'error'
- Class: net.Socket
- new net.Socket([options])
- socket.connect(port, [host], [connectListener])
- socket.connect(path, [connectListener])
- socket.bufferSize
- socket.setEncoding([encoding])
- socket.write(data, [encoding], [callback])
- socket.end([data], [encoding])
- socket.destroy()
- socket.pause()
- socket.resume()
- socket.setTimeout(timeout, [callback])
- socket.setNoDelay([noDelay])
- socket.setKeepAlive([enable], [initialDelay])
- socket.address()
- socket.unref()
- socket.ref()
- socket.remoteAddress
- socket.remotePort
- socket.localAddress
- socket.localPort
- socket.bytesRead
- socket.bytesWritten
- Event: 'lookup'
- Event: 'connect'
- Event: 'data'
- Event: 'end'
- Event: 'timeout'
- Event: 'drain'
- Event: 'error'
- Event: 'close'
- net.isIP(input)
- net.isIPv4(input)
- net.isIPv6(input)
- UDP / Datagram Sockets
- dgram.createSocket(type, [callback])
- Class: dgram.Socket
- Event: 'message'
- Event: 'listening'
- Event: 'close'
- Event: 'error'
- socket.send(buf, offset, length, port, address, [callback])
- socket.bind(port, [address], [callback])
- socket.close()
- socket.address()
- socket.setBroadcast(flag)
- socket.setTTL(ttl)
- socket.setMulticastTTL(ttl)
- socket.setMulticastLoopback(flag)
- socket.addMembership(multicastAddress, [multicastInterface])
- socket.dropMembership(multicastAddress, [multicastInterface])
- socket.unref()
- socket.ref()
- DNS
- dns.lookup(hostname, [family], callback)
- dns.resolve(hostname, [rrtype], callback)
- dns.resolve4(hostname, callback)
- dns.resolve6(hostname, callback)
- dns.resolveMx(hostname, callback)
- dns.resolveTxt(hostname, callback)
- dns.resolveSrv(hostname, callback)
- dns.resolveSoa(hostname, callback)
- dns.resolveNs(hostname, callback)
- dns.resolveCname(hostname, callback)
- dns.reverse(ip, callback)
- dns.getServers()
- dns.setServers(servers)
- Error codes
- HTTP
- http.METHODS
- http.STATUS_CODES
- http.createServer([requestListener])
- http.createClient([port], [host])
- Class: http.Server
- Event: 'request'
- Event: 'connection'
- Event: 'close'
- Event: 'checkContinue'
- Event: 'connect'
- Event: 'upgrade'
- Event: 'clientError'
- server.listen(port, [hostname], [backlog], [callback])
- server.listen(path, [callback])
- server.listen(handle, [callback])
- server.close([callback])
- server.maxHeadersCount
- server.setTimeout(msecs, callback)
- server.timeout
- Class: http.ServerResponse
- Event: 'close'
- Event: 'finish'
- response.writeContinue()
- response.writeHead(statusCode, [statusMessage], [headers])
- response.setTimeout(msecs, callback)
- response.statusCode
- response.statusMessage
- response.setHeader(name, value)
- response.headersSent
- response.sendDate
- response.getHeader(name)
- response.removeHeader(name)
- response.write(chunk, [encoding])
- response.addTrailers(headers)
- response.end([data], [encoding])
- http.request(options, [callback])
- http.get(options, [callback])
- Class: http.Agent
- http.globalAgent
- Class: http.ClientRequest
- http.IncomingMessage
- HTTPS
- URL
- Query String
- punycode
- Readline
- REPL
- Executing JavaScript
- Child Process
- Assert
- assert.fail(actual, expected, message, operator)
- assert(value, message), assert.ok(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])
- assert.doesNotThrow(block, [message])
- assert.ifError(value)
- TTY
- Zlib
- Examples
- zlib.createGzip([options])
- zlib.createGunzip([options])
- zlib.createDeflate([options])
- zlib.createInflate([options])
- zlib.createDeflateRaw([options])
- zlib.createInflateRaw([options])
- zlib.createUnzip([options])
- Class: zlib.Zlib
- Class: zlib.Gzip
- Class: zlib.Gunzip
- Class: zlib.Deflate
- Class: zlib.Inflate
- Class: zlib.DeflateRaw
- Class: zlib.InflateRaw
- Class: zlib.Unzip
- Convenience Methods
- zlib.deflate(buf, [options], callback)
- zlib.deflateRaw(buf, [options], callback)
- zlib.gzip(buf, [options], callback)
- zlib.gunzip(buf, [options], callback)
- zlib.inflate(buf, [options], callback)
- zlib.inflateRaw(buf, [options], callback)
- zlib.unzip(buf, [options], callback)
- Options
- Memory Usage Tuning
- Constants
- os
- Debugger
- Cluster
- How It Works
- cluster.schedulingPolicy
- cluster.settings
- cluster.isMaster
- cluster.isWorker
- Event: 'fork'
- Event: 'online'
- Event: 'listening'
- Event: 'disconnect'
- Event: 'exit'
- Event: 'setup'
- cluster.setupMaster([settings])
- cluster.fork([env])
- cluster.disconnect([callback])
- cluster.worker
- cluster.workers
- Class: Worker
- Smalloc
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() と同様に、もし expression
が false
に評価されると、
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
という特別なオブジェクトに加えます。
モジュールのローカル変数は関数に包まれているかのようにプライベートになります。
この例の場合、変数 PI
は circle.js
のプライベート変数です。
モジュールのルートとして関数 (たとえばコンストラクタ) を後悔したり、
プロパティを一つずつ代入するのではなく、完全なオブジェクトを一度に
公開したければ、exports
の代わりに module.exports
に代入します。
以下では、bar.js
は square
モジュールが公開するコンストラクタを
使用しています。
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.js
が a.js
をロードすると、a.js
は b.js
をロードします。
ポイントは、b.js
は a.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.js
は foo.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.exports
は exports
オブジェクトを通じて
参照することもできます。
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;
}
ガイドラインとして、もし exports
と module.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によって直接実行される場合、その module
が
require.main
に設定されます。
これは、ファイルが直接実行されたかを決定できることを意味します。
require.main === module
foo.js
ファイルの場合、node foo.js
と実行された場合にこれは true
になりますが、require('./foo')
で実行された場合は false
になります。
module
は filename
プロパティ (通常 __filename
と同じです)
を提供するため、現在のアプリケーションのエントリポイントは
require.main.filename
をチェックすることで得ることができます。
Addenda: Package Manager Tips#
Node の require()
は普通のディレクトリ構造をサポートできるよう汎用的に設計されています。
dpkg
や rpm
や npm
のようなパッケージ管理プログラムは修正なしに 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();
createObject を
addon.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 がSIGKILL
やSIGHUP
などの致命的なシグナルを受け取ると、終了コードは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
は既存のプロセスを検索するためのものです。 SIGINT
、SIGTERM
、そしてSIGKILL
は、ターゲットのプロセスが無条件に 終了する原因となります。
process.stdout#
stdout
に対する Writable Stream
です。
例: console.log
の定義
console.log = function(d) {
process.stdout.write(d + '\n');
};
process.stderr
と process.stdout
は他のストリームと異なり、
書き込みは通常ブロックします。
それらが通常ファイルや TTY のファイル記述子を参照しているケースでは、
それらはブロックします。
パイプを参照しているケースでは、他のストリームと同様にブロックしません。
Node が TTY のコンテキストで実行されているかチェックするには、
process.stderr
, process.stdout
, または process.stdin
の
isTTY
プロパティを参照します。
$ 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.stderr
と process.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 }
heapTotal
と heapUsed
は 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
(意図的にスタイル無し)
事前に定義された色は: white
、grey
、black
、blue
、cyan
、
green
、magenta
、red
、および yellow
です。
bold
、italic
、underline
、および 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)#
object
が RegExp
なら true
を、それ以外なら false
を返します。
var util = require('util');
util.isRegExp(/some regexp/)
// true
util.isRegExp(new RegExp('another regexp'))
// true
util.isRegExp({})
// false
util.isDate(object)#
object
が Date
なら 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)#
object
が Error
なら 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
から作られたオブジェクトに設定されます。
さらなる利便性のために、superConstructor
は constructor.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 namelistener
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
obj
が Buffer
かどうかテストします。
Class Method: Buffer.byteLength(string, [encoding])#
string
Stringencoding
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: 0length
Number, Optionalencoding
String, Optional, Default: 'utf8'
与えられたエンコーディングを使用して、string
をバッファの offset
から書き込みます。
offset
のデフォルトは 0
、encoding
のデフォルトは '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: 0end
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 - コピー先の BuffertargetStart
Number, Optional, Default: 0sourceStart
Number, Optional, Default: 0sourceEnd
Number, Optional, Default:buffer.length
バッファ間でコピーします。
ソースとターゲットの領域は重なっていても構いません。
targetStart
と sourceStart
のデフォルトは 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: 0end
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
NumbernoAssert
Boolean, Optional, Default: false- Return: Number
バッファの指定された位置を符号無し 8bit 整数として読み込みます。
もし noAssert
が true
なら 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
NumbernoAssert
Boolean, Optional, Default: false- Return: Number
バッファの指定された位置を符号無し 16bit 整数として読み込みます。
もし noAssert
が true
なら 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
NumbernoAssert
Boolean, Optional, Default: false- Return: Number
バッファの指定された位置を符号無し 32bit 整数として読み込みます。
もし noAssert
が true
なら 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
NumbernoAssert
Boolean, Optional, Default: false- Return: Number
バッファの指定された位置を符号付き 8bit 整数として読み込みます。
もし noAssert
が true
なら offset
の検証をスキップします。
これは offset
がバッファの終端を越えてしまう場合があることを意味します。
デフォルトは false
です。
バッファの内容を 2 の補数による符号付き値として扱うこと以外は
buffer.readUInt8
と同じように動作します。
buf.readInt16LE(offset, [noAssert])#
buf.readInt16BE(offset, [noAssert])#
offset
NumbernoAssert
Boolean, Optional, Default: false- Return: Number
バッファの指定された位置を符号付き 16bit 整数として読み込みます。
もし noAssert
が true
なら offset
の検証をスキップします。
これは offset
がバッファの終端を越えてしまう場合があることを意味します。
デフォルトは false
です。
バッファの内容を 2 の補数による符号付き値として扱うこと以外は
buffer.readUInt16
と同じように動作します。
buf.readInt32LE(offset, [noAssert])#
buf.readInt32BE(offset, [noAssert])#
offset
NumbernoAssert
Boolean, Optional, Default: false- Return: Number
バッファの指定された位置を符号付き 32bit 整数として読み込みます。
もし noAssert
が true
なら offset
の検証をスキップします。
これは offset
がバッファの終端を越えてしまう場合があることを意味します。
デフォルトは false
です。
バッファの内容を 2 の補数による符号付き値として扱うこと以外は
buffer.readUInt32
と同じように動作します。
buf.readFloatLE(offset, [noAssert])#
buf.readFloatBE(offset, [noAssert])#
offset
NumbernoAssert
Boolean, Optional, Default: false- Return: Number
バッファの指定された位置を 32bit 浮動小数点数として読み込みます。
もし noAssert
が true
なら 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
NumbernoAssert
Boolean, Optional, Default: false- Return: Number
バッファの指定された位置を 64bit 倍精度浮動小数点数として読み込みます。
もし noAssert
が true
なら 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
Numberoffset
NumbernoAssert
Boolean, Optional, Default: false
value
を符号無し 8bit 整数としてバッファの指定された位置に、
指定されたエンディアンで書き込みます。
value
は妥当な 8bit 符号無し整数でなければならないことに注意してください。
もし noAssert
が true
なら,value
と offset
の検証をスキップします。
これは、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
Numberoffset
NumbernoAssert
Boolean, Optional, Default: false
value
を符号無し 16bit 整数としてバッファの指定された位置に、
指定されたエンディアンで書き込みます。
value
は妥当な 16bit 符号無し整数でなければならないことに注意してください。
もし noAssert
が true
なら,value
と offset
の検証をスキップします。
これは、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
Numberoffset
NumbernoAssert
Boolean, Optional, Default: false
value
を符号無し 32bit 整数としてバッファの指定された位置に、
指定されたエンディアンで書き込みます。
value
は妥当な 32bit 符号無し整数でなければならないことに注意してください。
もし noAssert
が true
なら,value
と offset
の検証をスキップします。
これは、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
Numberoffset
NumbernoAssert
Boolean, Optional, Default: false
value
を符号付き 8bit 整数としてバッファの指定された位置に、
指定されたエンディアンで書き込みます。
value
は妥当な 8bit 符号付き整数でなければならないことに注意してください。
もし noAssert
が true
なら,value
と offset
の検証をスキップします。
これは、value
がこの関数で扱えるより大きな場合や、offset
がバッファの終端を越えてしまう場合は、静かに捨てられることを意味します。
正確性に確信がない限り、これらを使用すべきではありません。
デフォルトは false
です。
value
を 2 の補数による符号付き値として書き込むこと以外は
buffer.writeUInt8
と同じように動作します。
buf.writeInt16LE(value, offset, [noAssert])#
buf.writeInt16BE(value, offset, [noAssert])#
value
Numberoffset
NumbernoAssert
Boolean, Optional, Default: false
value
を符号付き 16bit 整数としてバッファの指定された位置に、
指定されたエンディアンで書き込みます。
value
は妥当な 16bit 符号付き整数でなければならないことに注意してください。
もし noAssert
が true
なら,value
と offset
の検証をスキップします。
これは、value
がこの関数で扱えるより大きな場合や、offset
がバッファの終端を越えてしまう場合は、静かに捨てられることを意味します。
正確性に確信がない限り、これらを使用すべきではありません。
デフォルトは false
です。
value
を 2 の補数による符号付き値として書き込むこと以外は
buffer.writeUInt16
と同じように動作します。
buf.writeInt32LE(value, offset, [noAssert])#
buf.writeInt32BE(value, offset, [noAssert])#
value
Numberoffset
NumbernoAssert
Boolean, Optional, Default: false
value
を符号付き 32bit 整数としてバッファの指定された位置に、
指定されたエンディアンで書き込みます。
value
は妥当な 32bit 符号付き整数でなければならないことに注意してください。
もし noAssert
が true
なら,value
と offset
の検証をスキップします。
これは、value
がこの関数で扱えるより大きな場合や、offset
がバッファの終端を越えてしまう場合は、静かに捨てられることを意味します。
正確性に確信がない限り、これらを使用すべきではありません。
デフォルトは false
です。
value
を 2 の補数による符号付き値として書き込むこと以外は
buffer.writeUInt32
と同じように動作します。
buf.writeFloatLE(value, offset, [noAssert])#
buf.writeFloatBE(value, offset, [noAssert])#
value
Numberoffset
NumbernoAssert
Boolean, Optional, Default: false
value
を 32bit 浮動小数点数としてバッファの指定された位置に、
指定されたエンディアンで書き込みます。
value
が 32bit 浮動小数点数でない場合の振る舞いは未定義であることに
注意してください。
もし noAssert
が true
なら,value
と offset
の検証をスキップします。
これは、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
Numberoffset
NumbernoAssert
Boolean, Optional, Default: false
value
を 64bit 倍精度浮動小数点数としてバッファの指定された位置に、
指定されたエンディアンで書き込みます。
value
は妥当な 64bit 倍精度浮動小数点数でなければならないことに注意してください。
もし noAssert
が true
なら,value
と offset
の検証をスキップします。
これは、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, Optionalend
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#
ストリームは、Readable、Writable、またはその両方 (Duplex) のいずれかになることができます。
全てのストリームは EventEmitter ですが、Readable、Writable、または Duplex のいずれであるかによって、独自のメソッドやプロパティを持ちます。
もしストリームが Readable とWritable の両方であるなら、 それは以下の全てのメソッドとイベントを実装します。 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 ストリームを含む例:
- クライアントの http レスポンス
- サーバの http リクエスト
- fs の ReadStream
- zlib のストリーム
- crypto のストリーム
- tcp のソケット
- child_process の標準出力と標準エラー出力
- process.stdin
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 ストリームを含む例:
- クライアントの http リクエスト
- サーバの http レスポンス
- fs の WriteStream
- zlib のストリーム
- crypto のストリーム
- tcp のソケット
- child_process の標準入力
- process.stdout, process.stderr
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 ストリームは Readable と Writable 両方のインターフェースを 実装したストリームです。使い方は上記を参照してください。
Duplex ストリームを含む例:
Class: stream.Transform#
Transform ストリームは、入力から何らかの方法で出力が計算される Duplex ストリームです。 それらは Readable と Writable 両方のインターフェースを実装します。 使い方は上記を参照してください。
Transform ストリームを含む例:
API for Stream Implementors#
どのストリームを実装する場合でも、パターンは同じです:
- それぞれの親クラスを拡張して、独自のサブクラスを作成する
(特に
util.inherits
メソッドはそのために役立ちます)。 - 内部のメカニズムがきちんとセットアップされることを確実にするために、 サブクラスのコンストラクタの中から親クラスのコンストラクタを呼び出す。
- 以下で詳述される、いくつかの特別なメソッドを実装する。
拡張するクラスと実装するメソッドは、あなたが書こうとしているストリームの種類に 依存します。
ユースケース |
クラス |
実装するメソッド |
---|---|---|
読み込みのみ |
||
書き込みのみ |
||
読み込みと書き込み |
||
書き込まれたデータを変換し、その結果を読み込む |
あなたの実装コードの中では、決して ストリーム利用者のための 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} (任意)
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'
が強制されます。
もし data
が Buffer
なら、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 を使用する暗号オブジェクトを作成して 返します。
algorithm
は createCipher()
の引数と同じです。
key
はアルゴリズムで使用される生のキーです。
iv
はinitialization
vector です。
key
と iv
は 'binary'
でエンコードされた文字列または
buffers でなければなりません
Class: Cipher#
データを暗号化するためのクラスです。
crypto.createCipher
および crypto.createCipheriv
から返されます。
暗号化オブジェクトは読み込みと書き込みの両方が可能な
ストリーム です。
書き込まれたプレーンテキストデータは、読み込み側に暗号化されたデータを
生成するために使われます。
レガシーな update()
および final()
メソッドもサポートされます。
cipher.update(data, [input_encoding], [output_encoding])#
data
で暗号を更新します。
input_encoding
で与えられるエンコーディングは 'utf8'
、'ascii'
、'binary'
のいずれかです。
エンコーディングが与えられなかった場合はバッファが期待されます。
もし data
が Buffer
なら、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_padding
が false
の場合、入力データ全体の長さは
暗号ブロックサイズの倍数でなければなりません。
でなければ、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
で更新します。
エンコーディングが与えられなかった場合はバッファが期待されます。
もし data
が Buffer
なら、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])#
署名されたデータを object
と signature
で検証します。
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
: certificateinkey
: private keycertfile
: all CA certs concatenated in one file likecat 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" が負荷されていることに注意してください):
鍵の生成は高価な処理であるため、「一時的」な方法はパフォーマンスの面で 不利かもしれません。
tls.getCiphers()#
サポートされている SSL 暗号名の配列を返します。
例:
var ciphers = tls.getCiphers();
console.log(ciphers); // ['AES128-SHA', 'AES256-SHA', ...]
tls.createServer(options, [secureConnectionListener])#
新しい tls.Server を作成します。
connectionListener
は secureConnection イベントのリスナとして
自動的に登録されます。
options
は以下を持つことができます:
pfx
: PFX または PKCS12 でエンコードされた秘密鍵、証明書、および CA の 証明書を含む文字列またはバッファ (key
、cert
、および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-SHA256
とAES128-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
の場合、サーバは提供された認証局の リストによって認証されていないコネクションを破棄します. このオプションはrequestCert
がtrue
の場合だけ効果があります。 デフォルトはfalse
です。NPNProtocols
: NPN プロトコルで使用可能な文字列またはBuffer
の配列 (プロトコルはその優先度に応じて並んでいる必要があります)。SNICallback(servername, cb)
: クライアントが TLS 拡張の SNI を サポートしている場合に呼び出される関数です。 二つの引数、servername
とcb
が渡されます。SNICallback
は、cb(null, ctx)
を呼び出す必要があります。ctx
はSecureContext のインスタンスです (SecureContext を取得するためにcrypto.createCredentials(...).context
を使用することができます)。SNICallback
が渡されなかった場合は、デフォルトのコールバックとして 後述する高水準 API が使用されます。sessionTimeout
: サーバによって作成された TLS セッション識別子および TLS セッションチケットがタイムアウトするまでの秒数を指定する整数値です。 より詳細は SSL_CTX_set_timeout を参照してください。sessionIdContext
: セッション再開のための識別子となる文字列です。requestCedrt
がtrue
の場合、デフォルトはコマンドライン引数から 生成された 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])#
与えられた port
と host
(旧 API) または options.port
と options.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 オブジェクトを構築します。
socket
は net.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()
は、cleartext
と encrypted
ストリームを
プロパティとして持つ SecurePair
オブジェクトを返します。
注意: cleartext
は tls.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])#
指定の port
と host
で接続の受け入れを開始します。
host
が省略されると、サーバはどんな IPv4 アドレスからのコネクションも受け入れます (INADDR_ANY
)。
この関数は非同期です。
最後の引数 callback
はサーバがバインドされると呼び出されます。
より詳細は net.Server
を参照してください。
server.close()#
サーバが新しい接続を受け入れることを終了します。
この関数は非同期で、サーバが最終的にクローズされるとサーバは 'close'
イベントを生成します。
server.address()#
オペレーティングシステムから報告された、サーバにバインドされたアドレスと アドレスファミリ名、ポートを返します。 より詳しくは net.Server.address() を参照してください。
server.addContext(hostname, credentials)#
クライアントが要求してきた SNI ホスト名と hostname
(ワイルドカードを使用可能)
がマッチした場合のセキュリティコンテキストを追加します。
credentials
は key
、cert
、そして 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_CIPHERS
で SSL_CIPHER_get_name()
および SSL_CIPHER_get_version()
を
参照してください。
tlsSocket.renegotiate(options, callback)#
TLSの再ネゴシエーションを開始します。
options
は以下のフィールドを含むことが出来ます:
rejectUnauthorized
、requestCert
(詳細は tls.createServer 参照)。
callback(err)
は再ネゴシエーションが成功で完了すると、err
が null
で
実行されます。
注意: 相手側の証明書は、セキュアな接続が確立された後で利用可能になります。
更に注意: サーバとして実行される場合、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.stat
は fs.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)
で、
stats
は fs.Stats オブジェクトです。
詳細は fs.Stats の節を参照してください。
より詳しくは後述の fs.Stats の節を参照してください。
fs.lstat(path, callback)#
非同期の lstat(2)。コールバックは 2 つの引数を受け取る (err, stats)
で、
stats
は fs.Stats
オブジェクトです。
lstat()
はパスがシンボリックリンクだった場合に、
参照先のファイルではなくそのリンク自身が調べられる点を除いて stat()
と同じす。
fs.fstat(fd, callback)#
非同期の fstat(2)。コールバックは 2 つの引数を受け取る (err, stats)
で、
stats
は fs.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
を書き込みます。
offset
と length
は書き込まれるバッファの部分を決定します。
position
はデータが書き込まれる位置をファイルの先頭からのオフセットで示します。
position
が数値型ではない (typeof position !== 'number'
) 場合、
データは現在の位置から書き込まれます。pwrite(2) を参照してください。
コールバックは 3 つの引数が与えられる (err, written, buffer)
で、
written
は buffer
から書き込まれたバイト数を示します。
同じファイルに対してコールバックされるのを待つことなく 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
はファイルの読み込みを開始する位置を指定する整数です。
position
が null
の場合、データは現在の位置から読み込まれます。
コールバックは3つの引数が与えられる (err, bytesRead, buffer)
です。
fs.readSync(fd, buffer, offset, length, position)#
同期版の fs.read
。bytesRead
の数を返します。
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.readFile
。filename
の内容を返します。
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 の persistent
と interval
の二つのメンバを含むオブジェクトです。
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.mtime
と prev.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
のメンバは persistent
と recursive
です。
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 }
atime
、mtime
、birthtime
、そして ctime
は Date
オブジェクトであり、その値を比較するには適切な方法があるということに
注意してください。もっとも一般的に使われる 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 システムでは ctime
は birthtime
を保持していました。v0.12 では、Unix システムでは決してそうではなかったように
ctime
は "creation time" ではないことに注意してください。
fs.createReadStream(path, [options])#
新しい ReadStream オブジェクトを返します (Readable Stream
を参照してください)。
options
は以下のデフォルト値を持つオブジェクトです:
{ flags: 'r',
encoding: null,
fd: null,
mode: 0666,
autoClose: true
}
ファイル全体を読み込む代わりに一部の範囲を読み込むため、
options
に start
および end
を含めることができます。
start
と end
はどちらも包含的で0から始まります。
encoding
は 'utf8'
、'ascii'
、または 'base64'
です。
autoClose
が false
の場合、エラーが発生しない限りファイル記述子は
クローズされません。ファイルをクローズし、ファイル記述子が
リークしないようにするのはあなたの責務です。
autoClose
が true
に設定されると (デフォルトの振る舞いです)、
error
または end
によってファイル記述子は自動的にクローズされます。
100 バイトの長さを持つファイルの最後の 10 バイトを読み込む例:
fs.createReadStream('sample.txt', {start: 90, end: 99});
Class: fs.ReadStream#
ReadStream
は Readable 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#
WriteStream
は Writable 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
}
allowHalfOpen
が true
だと、反対側のソケットが 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])#
指定された port
と host
でコネクションの受け入れを開始します。
host
が省略されると、サーバはどんな IPv4 アドレスへの接続も受け入れます
(INADDR_ANY
)。
ポート番号に 0 を指定すると、ランダムなポートが割り当てられます。
バックログは保留された接続のキューの最大長です。
実際の長さは Linux では tcp_max_syn_backlog
や somaxconn
など、
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
Stringcallback
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
Objectcallback
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 した子プロセスに送られても動作します。
コールバックは err
と count
の二つの引数を取るべきです。
Event: 'listening'#
server.listen()
が呼ばれた後、サーバがバインドされると生成されます。
Event: 'connection'#
- Socket object The connection object
新しいコネクションが作成されると生成されます。
socket
は net.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
および writable
に true
を設定すると、
ソケットへの読み込みまたは書き込みが可能になります
(注意: fd
が渡された場合のみ作用します)。
allowHalfOpen
については createServer()
および 'end'
イベントを参照してください。
socket.connect(port, [host], [connectListener])#
socket.connect(path, [connectListener])#
与えられたソケットでコネクションをオープンします。
port
と host
が与えられた場合、
ソケットは 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 アルゴリズムを使用し、データを送信する前にバッファリングします。
noDelay
に true
を設定すると、データは 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#
リモートポートの数値表現です。
たとえば、80
や 21
。
socket.localAddress#
リモートクライアントが接続しているローカル IP アドレスを表現する文字列です。
たとえば、 '0.0.0.0'
をリッスンしていて、クライアントが '192.168.1.1'
に接続した場合、この値は '192.168.1.1'
になります。
socket.localPort#
ローカルポートの数値表現です。
たとえば、80
や 21
。
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
指定された種類のデータグラムソケットを作成します。
妥当な種類は udp4
と udp6
です。
オプションのコールバックは message
イベントのリスナーとして加えられます。
データグラムを受信したい場合は socket.bind()
を呼び出します。
socket.bind()
は「全てのインタフェース」のアドレスにランダムなポート
(udp4
と udp6
ソケットの両方で正しいものです) をバインドします。
そのアドレスとポートは socket.address().address
および
socket.address().port
で取得することができます。
Class: dgram.Socket#
dgram Scoket クラスはデータグラム機能をカプセル化します。
それは dgram.createSocket(type, [callback])
を通じて生成されます。
Event: 'message'#
msg
Buffer object. メッセージrinfo
Object. リモートアドレスの情報
ソケット上で新しいデータグラムが到着した時に生成されます。
msg
は Buffer
で、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
オクテット必要で、推奨されるIPv4
のMTU
は576
です (典型的なダイヤルアップ型アプリケーションのMUT
推奨値)。IPv6
では最小のMTU
は1280
オクテットですが、フラグメントを再構築する バッファサイズは最低1500
オクテットが必要です。68
オクテットはとても小さいので、もっとも現代的なリンク層技術では、 最小のMTU
は1500
です (イーサネットと同じです)。
パケットが通過する各リンクの MTU をあらかじめ知ることは
できないこと、(受信側の) MTU
より大きなデータグラムを送信しても
通常は動作しないことに注意してください
(パケットは送り主に知らされることなく黙って捨てられ、
意図した受信者に到達することはありません)。
socket.bind(port, [address], [callback])#
port
Integeraddress
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()#
オブジェクトが持っているソケットのアドレス情報を返します。
このオブジェクトは address
、port
、そして 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
StringmulticastInterface
String, Optional
IP_ADD_MEMBERSHIP
ソケットオプションを設定し、マルチキャストグループに参加することをカーネルに伝えます。
multicastInterface
が指定されなかった場合は、全ての妥当なインタフェースをメンバーシップに加えようとします。
socket.dropMembership(multicastAddress, [multicastInterface])#
multicastAddress
StringmulticastInterface
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
に渡す必要はありません)。
エラー時、err
は Error
オブジェクトで、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
の各要素の種類はレコードの種類によって決まり、
対応する後述のルックアップメソッドで記述されます。
エラー時、err
は Error
オブジェクトで、
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
レコード) だけを問い合わせます。
addresses
は hostname
で利用可能なテキストレコードの配列です。
(例、['v=spf1 ip4:0.0.0.0 ~all']
)
dns.resolveSrv(hostname, callback)#
dns.resolve()
と同じですが、サービスレコード (SRV
レコード) だけを問い合わせます。
addresses
は hostname
で利用可能な 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
レコード)
だけを問い合わせます。
address
は hostname
で利用可能なネームサーバレコードの配列です
(例 ['ns1.example.com', 'ns2.example.com']
)。
dns.resolveCname(hostname, callback)#
dns.resolve()
と同じですが、別名レコード (CNAME
レコード)
だけを問い合わせます。
address
は domain
で利用可能な別名レコードの配列です
hostname
(e.g., ['bar.example.com']
)。
dns.reverse(ip, callback)#
IP アドレスからホスト名の配列へ逆引きで解決します。
コールバックは引数 (err, hostname)
を持ちます。
エラー時、err
は Error
オブジェクトで、
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 クライアントを構築します。
port
と host
は接続するサーバを示します。
Class: http.Server#
これは以下のイベントを持つ EventEmitter です:
Event: 'request'#
function (request, response) { }
リクエストの度に生成されます。
コネクションごとに複数のリクエストがあるかもしれないことに注意してください
(Keep Alive なコネクションの場合)。
request
は http.IncomingMessage のインスタンス、
response
は http.ServerResponse のインスタンスです。
Event: 'connection'#
function (socket) { }
新しい TCP ストリームが確立した時。
socket
は net.Socket
型のオブジェクトです。
通常の利用者がこのイベントにアクセスしたくなることはないでしょう。
とりわけ、ソケットはプロトコルパーサにアタッチされるため、
readable
イベントを生成しません。
socket
は request.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_backlog
や somaxconn
など、
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
Objectcallback
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
Numbercallback
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
Numbercallback
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()
サポート。hostname
はhost
を上書きします。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 キープアライブパケットを送信する間隔です。keepAlive
がtrue
に設定された場合だけ関係があります。
オプションの 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 キープアライブパケットを送信する間隔。keepAlive
がtrue
に設定された場合だけ関係があります。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
Numbercallback
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)。
例: OK
や Internal 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 サーバオブジェクトを返します。
option
は tls.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()
で扱える文字列をサポートします。hostname
はhost
を上書きします。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
:pathname
とsearch
を連結した文字列。例:
'/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
の末尾に:
(コロン) があってもなくても同じように扱われます。http
、https
、ftp
、gopher
、file
は末尾に://
(コロン、スラッシュ、スラッシュ) が付けられます。mailto
、xmpp
、aim
、sftp
、foo
など、その他のプロトコルは末尾に:
(コロン) が付けられます。
auth
が与えられると使われます。hostname
はhost
が与えられなかった場合だけ使われます。port
はhost
が与えられなかった場合だけ使われます。host
はhostname
、port
の位置で使われます。pathname
の先頭に/
(スラッシュ) があってもなくても同じように扱われます。search
はquery
の位置で使われます。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 つのエントリを含む配列を返すことが期待されます:
補完によってマッチするエントリの配列。
マッチングに使用された部分文字列。
それは次のようになります:
[[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.stdin
と
process.stdout
が使用されます。
var readline = require('readline');
var rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
readline のインスタンスを作成すると、ほとんどの場合 'line'
イベントを
監視することになります。
もしこのインスタンスの terminal
が true
の場合、
output
ストリームはもし outout.columns
プロパティが定義されていれば
それに適合し、カラム幅が変更されると output
上で
'resize'
イベントが生成されます
(process.stdout
が TTY の場合、それは自動的に行われます)。
Class: Interface#
入力と出力を持つ readline インタフェースを表現するクラスです。
rl.setPrompt(prompt)#
プロンプトを設定します。
たとえば、コマンドプロンプトで node
コマンドを実行すると、
>
を見ることができます。これが Node のプロンプトです。
rl.prompt([preserveCursor])#
ユーザからの入力を 1 行読み込みます。
現在の setPrompt()
の値を新しい行に出力し、
ユーザに新しい入力エリアを与えます。
preserveCursor
を true
に設定すると、カーソル位置が
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])#
data
を output
ストリームに出力します。
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.runInThisContext
と eval
で同じコードを実行する例:
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)
機能を提供します。
これは完全にノンブロッキングな方法で子プロセスの stdin
、stdout
、
そして stderr
を通じたデータストリームを実現します。
(いくつかのプログラムは内部的にバッファリングされた I/O を使うことに
注意してください。それは node.js には影響しませんが、
子プロセスに送ったデータがすぐに消費されるとは限らないことを意味します)。
子プロセスの生成は require('child_process').spawn()
または
require('child_process').fork()
を使います。
それぞれの意味論は以下で説明するようにわずかに異なります。
Class: ChildProcess#
ChildProcess
は EventEmitter です。
子プロセスは常に 3 本のストリームと関連づけられています。
child.stdin
、child.stdout
、そして child.stderr
です。
それらは親プロセスの標準入出力ストリームを共有するかもしれませんし、
独立したストリームオブジェクトにパイプでつながれているかもしれません。
Event: 'error'#
err
{Error Object} エラー。
次の場合に生成されます:
- プロセスを起動できなかった、または
- プロセスを殺すことができなかった、または
- 何らかの理由で子プロセスにメッセージを送信することが失敗した。
エラーが発生した後、'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` に設定される
.connected
が false
の場合、メッセージを送信することはできません。
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
ObjectsendHandle
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 コネクションをクローズし、
他の接続を持たない子プロセスが自然に終了することを可能にします。
このメソッドを呼び出すと、親プロセスと子プロセスの両方で .connected
は
false
に設定され、メッセージを送信することはできなくなります。
プロセスが受信するメッセージがなければ、おそらくはすぐに '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
を実行して stdout
、stderr
、および終了コードを取得する例:
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 に対応します。
要素の値は以下のいずれかです:
'pipe'
- 子プロセスと親プロセスの間でパイプを作成します。 パイプの親側の端点はchild_process
オブジェクトのプロパティChildProcess.stdio[fd]
として親プロセスに公開されます。 fd 0~2 はそれぞれ、ChildProcess.stdin
、ChildProcess.stdout
、ChildProcess.stderr
としても参照可能です。'ipc'
- 親プロセスと子プロセスの間でメッセージパッシングのための IPC チャネル/ファイル記述子を作成します。ChildProcess
は標準入出力に高々一つの IPC ファイル記述子を持ちます。 このオプションを設定すると、ChildProcess.send()
メソッドが有効になります。 子プロセスがこのファイル記述子に JSON メッセージを書き込むと、 それはChildProcess.on('message')
を引き起こします。 子プロセスが Node.js プログラムなら、IPC チャネルの存在はprocess.send()
およびprocess.on('message')
を有効にします。'ignore'
- 子プロセスにファイル記述子を設定しません。 Node は子プロセスを起動する際、常に fd 0~2 をオープンすることに 注意してください。これらのうちのどれかが'ignore'
の場合、node は/dev/null
をオープンして、それを子プロセスの fd に割り当てます。Stream
オブジェクト - tty、ファイル、ソケット、またはパイプを参照する 読み込みまたは書き込み可能なストリームを子プロセスと共有します。 ストリームの下層にあるファイル記述子は、子プロセスのstdio
配列の 対応する位置にコピーされます。 ストリームは下層のファイル記述を持っていなければならないことに 注意してください (ファイルストリームは'open'
イベントが発生するまで それを持ちません)。- 非負整数 - 整数の値を親プロセスが現在オープンしているファイル記述子として
解釈されます。
それは
Stream
オブジェクトの場合と同様に子プロセスに共有されます。 null
、undefined
- デフォルト値を使用します。stdio
のfd
が 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)
を得ます。
成功すると、error
は null
になります。
エラーだと、error
は Error
のインスタンスとなり、
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)#
actual
と expected
を operator
で区切ったメッセージを持つ例外を
スローします。
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.ReadStream
と tty.WriteStream
クラスを持ちます。
多くのケースでは、これらを直接使う必要はありません。
node は TTY コンテキストの中にいるかどうかを検出し、
process.stdin
は tty.ReadStream
のインスタンスに、
process.stdout
は tty.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)#
mode
は true
または 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#Advanced の
deflateInit2
および 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 つあります。
server.listen({fd: 7})
メッセージはマスタに渡されてるため、 ワーカのファイル記述子 7 が参照するものではなく、 親プロセスの ファイル記述子 7 がリスニングされてそのハンドルがワーカに 渡されます。server.listen(handle)
明示的なハンドルをリスニングするとマスタプロセスは 関与することなく、ワーカは与えられたハンドルを使うことになります。 ワーカがすでにハンドルを持っているなら、何をしようとしているか あなたは分かっているでしょう。'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
が未定義だと isMaster
は true
になります。
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 objectaddress
Object
ワーカが net.Server.listen()
を呼び出した後、(net や http などの) サーバでは
'listening'
イベントが生成され、マスタの cluster
でも 'listening'
イベントが生成されます。
イベントハンドラは二つの引数を伴って実行されます。
worker
はワーカオブジェクトを、address
オブジェクトは
以下の接続プロパティを含みます:
address
、prot
、そして 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
に設定されます。
process
で 'disconnect'
イベントが生成されるとワーカが process.exit(0)
を呼び出し、.suicide
が true
にならないことに注意してください。
これは偶発的な切断を防ぎます。
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
ObjectsendHandle
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