| NODE(1) |
| ======= |
| Ryan Dahl <ry@tinyclouds.org> |
| Version, 0.1.21, 2009.12.06 |
| |
| |
| == NAME |
| |
| node - evented I/O for V8 javascript |
| |
| |
| |
| == SYNOPSIS |
| |
| An example of a web server written with Node which responds with "Hello |
| World": |
| |
| ---------------------------------------- |
| var sys = require("sys"), |
| http = require("http"); |
| http.createServer(function (request, response) { |
| response.sendHeader(200, {"Content-Type": "text/plain"}); |
| response.sendBody("Hello World\n"); |
| response.finish(); |
| }).listen(8000); |
| sys.puts("Server running at http://127.0.0.1:8000/"); |
| ---------------------------------------- |
| |
| To run the server, put the code into a file called +example.js+ and execute |
| it with the node program |
| |
| ---------------------------------------- |
| > node example.js |
| Server running at http://127.0.0.1:8000/ |
| ---------------------------------------- |
| |
| |
| == API |
| |
| Node supports 3 string encodings. UTF-8 (+"utf8"+), ASCII (+"ascii"+), and |
| Binary (+"binary"+). +"ascii"+ and +"binary"+ only look at the first 8 bits |
| of the 16bit javascript string characters. Both are relatively fast--use |
| them if you can. +"utf8"+ is slower and should be avoided when possible. |
| |
| Unless otherwise noted, functions are all asynchronous and do not block |
| execution. |
| |
| |
| === Global Objects |
| |
| +GLOBAL+ :: |
| The global namespace object. |
| |
| +process+ :: |
| The process object. Most stuff lives in here. See the "process object" |
| section. |
| |
| +require(path)+ :: |
| See the modules section. |
| |
| +require.paths+ :: |
| The search path for absolute path arguments to +require()+. |
| |
| +__filename+ :: |
| The filename of the script being executed. |
| |
| +module+ :: |
| A reference to the current module (of type +process.Module+). In particular |
| +module.exports+ is the same as the +exports+ object. See +src/process.js+ for |
| more information. |
| |
| |
| |
| === The +process+ Object |
| |
| [cols="1,2,10",options="header"] |
| |========================================================= |
| | Event | Parameters | Notes |
| | +"exit"+ | +code+ | Made when the process exits. |
| A listener on this event should not try to perform |
| I/O since the process will forcibly exit in less |
| than microsecond. However, it is a good hook to |
| perform constant time checks of the module's |
| state (like for unit tests). |
| + |
| The parameter +code+ is the integer exit code |
| passed to +process.exit()+. |
| | +"uncaughtException"+ | +exception+ | Emitted when an exception |
| bubbles all the way down to |
| the event loop. If a listener |
| is added for this exception, |
| the default action (which is |
| to print a stack trace and |
| exit) will not occur. |
| | +"SIGINT"+, +"SIGUSR1"+, ... | (none) | Emitted when the processes receives a signal. |
| See sigaction(2) for a list of standard POSIX |
| signal names such as SIGINT, SIGUSR1, etc. |
| |========================================================= |
| |
| +process.ARGV+ :: |
| An array containing the command line arguments. |
| |
| +process.ENV+ :: |
| An object containing the user environment. See environ(7). |
| |
| +process.pid+ :: |
| The PID of the process. |
| |
| +process.platform+ :: |
| What platform you're running on. +"linux2"+, +"darwin"+, etc. |
| |
| +process.memoryUsage()+ :: |
| Returns the memory usage of the Node process. It looks like this |
| + |
| ---------------------- |
| { |
| "rss": 4935680, |
| "vsize": 41893888, |
| "heapTotal": 1826816, |
| "heapUsed": 650472 |
| } |
| ---------------------- |
| + |
| +heapTotal+ and +heapUsed+ refer to V8's memory usage. |
| |
| +process.exit(code=0)+:: |
| Ends the process with the specified code. By default it exits with the |
| success code 0. |
| |
| +process.cwd()+:: |
| Returns the current working directory of the process. |
| |
| +process.umask(mask)+ :: |
| Sets the process's file mode creation mask. Child processes inherit the mask |
| from the parent process. |
| - returns the old mask. |
| |
| +process.kill(pid, signal="SIGTERM")+ :: |
| Send a signal to a process. +pid+ is the process id and +signal+ is the |
| signal to send; for example, "SIGINT" or "SIGUSR1". See kill(2) for more |
| information. |
| |
| +process.watchFile(filename, [options,] listener)+:: |
| Watch for changes on +filename+. The callback +listener+ will be called each |
| time the file changes. |
| + |
| The second argument is optional. The +options+ if provided should be an |
| object containing two members a boolean, +persistent+, and +interval+, a |
| polling value in milliseconds. The default is +{persistent: true, interval: |
| 0}+. |
| + |
| The +listener+ gets two arguments the current stat object and the previous |
| stat object: |
| + |
| ------------------------- |
| process.watchFile(f, function (curr, prev) { |
| sys.puts("the current mtime is: " + curr.mtime); |
| sys.puts("the previous mtime was: " + prev.mtime); |
| }); |
| ------------------------- |
| + |
| These stat objects are instances of +posix.Stat+. |
| |
| +process.unwatchFile(filename)+:: |
| Stop watching for changes on +filename+. |
| |
| +process.compile(source, scriptOrigin)+:: |
| Just like +eval()+ except that you can specify a +scriptOrigin+ for better |
| error reporting. |
| |
| +process.mixin([deep], target, object1, [objectN])+ :: |
| Extend one object with one or more others, returning the modified object. |
| If no target is specified, the +GLOBAL+ namespace itself is extended. |
| Keep in mind that the target object will be modified, and will be returned |
| from +process.mixin()+. |
| + |
| If a boolean true is specified as the first argument, Node performs a deep |
| copy, recursively copying any objects it finds. Otherwise, the copy will |
| share structure with the original object(s). |
| + |
| Undefined properties are not copied. However, properties inherited from the |
| object's prototype will be copied over. |
| |
| === System module |
| |
| These function are in the module +"sys"+. Use +require("sys")+ to access |
| them. |
| |
| +puts(string)+:: |
| Outputs the +string+ and a trailing new-line to +stdout+. |
| |
| +print(string)+:: |
| Like +puts()+ but without the trailing new-line. |
| |
| +debug(string)+:: |
| A synchronous output function. Will block the process and |
| output the string immediately to stdout. |
| |
| +inspect(object)+ :: |
| Return a string representation of the +object+. (For debugging.) |
| |
| +exec(command)+:: |
| Executes the command as a child process, buffers the output and returns it |
| in a promise callback. |
| + |
| ---------------------------------------- |
| var sys = require("sys"); |
| sys.exec("ls /").addCallback(function (stdout, stderr) { |
| puts(stdout); |
| }); |
| ---------------------------------------- |
| + |
| - on success: stdout buffer, stderr buffer |
| - on error: exit code, stdout buffer, stderr buffer |
| |
| |
| |
| === Events |
| |
| Many objects in Node emit events: a TCP server emits an event each time |
| there is a connection, a child process emits an event when it exits. All |
| objects which emit events are are instances of +process.EventEmitter+. |
| |
| Events are represented by a camel-cased string. Here are some examples: |
| +"connection"+, +"receive"+, +"messageBegin"+. |
| |
| Functions can be then be attached to objects, to be executed when an event |
| is emitted. These functions are called _listeners_. |
| |
| Some asynchronous file operations return an +EventEmitter+ called a |
| _promise_. A promise emits just a single event when the operation is |
| complete. |
| |
| ==== +process.EventEmitter+ |
| |
| All EventEmitters emit the event +"newListener"+ when new listeners are |
| added. |
| |
| [cols="1,2,10",options="header"] |
| |========================================================= |
| | Event | Parameters | Notes |
| |
| | +"newListener"+ | +event, listener+| This event is made |
| any time someone adds |
| a new listener. |
| |========================================================= |
| |
| +emitter.addListener(event, listener)+ :: |
| Adds a listener to the end of the listeners array for the specified event. |
| + |
| ---------------------------------------- |
| server.addListener("connection", function (socket) { |
| puts("someone connected!"); |
| }); |
| ---------------------------------------- |
| |
| +emitter.removeListener(event, listener)+ :: |
| Remove a listener from the listener array for the specified event. |
| *Caution*: changes array indices in the listener array behind the listener. |
| |
| +emitter.listeners(event)+ :: |
| Returns an array of listeners for the specified event. This array can be |
| manipulated, e.g. to remove listeners. |
| |
| +emitter.emit(event, arg1, arg2, ...)+ :: |
| Execute each of the listeners in order with the supplied arguments. |
| |
| ==== +process.Promise+ |
| |
| +process.Promise+ inherits from +process.eventEmitter+. A promise emits one of two |
| events: +"success"+ or +"error"+. After emitting its event, it will not |
| emit anymore events. |
| |
| [cols="1,2,10",options="header"] |
| |========================================================= |
| | Event | Parameters | Notes |
| | +"success"+ | (depends) | |
| | +"error"+ | (depends) | |
| | +"cancel"+ | (depends) | |
| |========================================================= |
| |
| +promise.addCallback(listener)+ :: |
| Adds a listener for the +"success"+ event. Returns the same promise object. |
| |
| +promise.addErrback(listener)+ :: |
| Adds a listener for the +"error"+ event. Returns the same promise object. |
| |
| +promise.addCancelback(listener)+ :: |
| Adds a listener for the +"cancel"+ event. Returns the same promise object. |
| |
| +promise.emitSuccess(arg1, arg2, ...)+ :: |
| If you created the promise (by doing +new process.Promise()+) then call |
| +emitSuccess+ to emit the +"success"+ event with the given arguments. |
| + |
| (+promise.emit("success", arg1, arg2, ...)+ should also work, but doesn't at |
| the moment due to a bug; use +emitSuccess+ instead.) |
| |
| +promise.emitError(arg1, arg2, ...)+ :: |
| Emits the +"error"+ event. |
| |
| +promise.emitCancel(arg1, arg2, ...)+ :: |
| Emits the +"cancel"+ event. You may still get a +"success"+ or +"error"+ |
| callback if the promise giver does not handle the cancel event. Use |
| +promise.cancel()+ to ignore any later events. |
| |
| +promise.cancel()+ :: |
| Clears all +"success"+ and +"error"+ event listeners from the promise, then |
| emits the +"cancel"+ event. Whether or not the promise is actually canceled |
| or not depends on the promise giver. This also clears Promise.timeout() if one |
| was set. |
| |
| +promise.timeout(timeout = undefined)+ :: |
| If the +timeout+ parameter is provided, the promise will emit an +"error"+ |
| event after the given amount of millseconds. The timeout is canceled by any |
| +"success"+, +"error"+ or +"cancel"+ event being emitted by the Promise. |
| + |
| To tell apart a timeout from a regular "error" event, use the following test: |
| + |
| ---------------------------------------- |
| promise.addErrback(function(e) { |
| if (e instanceof Error && e.message === "timeout") { |
| // handle timeout |
| } else { |
| // handle regular error |
| } |
| }); |
| ---------------------------------------- |
| + |
| If the +timeout+ parameter is not provided, the current timeout value, if any, |
| is returned. |
| + |
| |
| +promise.wait()+ :: |
| Blocks futher execution until the promise emits a success or error event. |
| Events setup before the call to +promise.wait()+ was made may still be |
| emitted and executed while +promise.wait()+ is blocking. |
| + |
| If there was a single argument to the +"success"+ event then it is returned. |
| If there were multiple arguments to +"success"+ then they are returned as an |
| array. |
| + |
| If +"error"+ was emitted instead, +wait()+ throws an error. |
| + |
| *IMPORTANT* +promise.wait()+ is not a true fiber/coroutine. If any other |
| promises are created and made to wait while the first promise waits, the |
| first promise's wait will not return until all others return. The benefit of |
| this is a simple implementation and the event loop does not get blocked. |
| Disadvantage is the possibility of situations where the promise stack grows |
| infinitely large because promises keep getting created and keep being told |
| to wait(). Use +promise.wait()+ sparingly--probably best used only during |
| program setup, not during busy server activity. |
| |
| |
| === Standard I/O |
| |
| Standard I/O is handled through a special object +process.stdio+. stdout and |
| stdin are fully non-blocking (even when piping to files). stderr is |
| synchronous. |
| |
| [cols="1,2,10",options="header"] |
| |========================================================= |
| | Event | Parameters | Notes |
| |
| | +"data"+ | +data+ | Made when stdin has received a chunk of data. |
| Depending on the encoding that stdin was opened |
| with, +data+ will be a string. This event will |
| only be emited after +process.stdio.open()+ has |
| been called. |
| | +"close"+ | | Made when stdin has been closed. |
| |========================================================= |
| |
| +process.stdio.open(encoding="utf8")+:: |
| Open stdin. The program will not exit until +process.stdio.close()+ has been |
| called or the +"close"+ event has been emitted. |
| |
| +process.stdio.write(data)+:: |
| Write data to stdout. |
| |
| +process.stdio.writeError(data)+:: |
| Write data to stderr. Synchronous. |
| |
| +process.stdio.close()+:: |
| Close stdin. |
| |
| |
| === Modules |
| |
| Node uses the CommonJS module system |
| |
| Node has a simple module loading system. In Node, files and modules are in |
| one-to-one correspondence. As an example, +foo.js+ loads the module |
| +circle.js+ in the same directory. |
| |
| The contents of +foo.js+: |
| |
| ---------------------------------------- |
| var circle = require("./circle"), |
| var sys = require("sys"); |
| sys.puts("The area of a circle of radius 4 is " + circle.area(4)); |
| ---------------------------------------- |
| |
| The contents of +circle.js+: |
| |
| ---------------------------------------- |
| var PI = 3.14; |
| |
| exports.area = function (r) { |
| return PI * r * r; |
| }; |
| |
| exports.circumference = function (r) { |
| return 2 * PI * r; |
| }; |
| ---------------------------------------- |
| |
| The module +circle.js+ has exported the functions +area()+ and |
| +circumference()+. To export an object, add to the special +exports+ |
| object. (Alternatively, one can use +this+ instead of +exports+.) Variables |
| local to the module will be private. In this example the variable +PI+ is |
| private to +circle.js+. The function +puts()+ comes from the module +"sys"+, |
| which is a built-in module. Modules which are not prefixed by +"./"+ are |
| built-in module--more about this later. |
| |
| A module prefixed with +"./"+ is relative to the file calling +require()+. |
| That is, +circle.js+ must be in the same directory as +foo.js+ for |
| +require("./circle")+ to find it. |
| |
| Without the leading +"./"+, like +require("mjsunit")+ the module is searched |
| for in the +require.paths+ array. +require.paths+ on my system looks like |
| this: |
| |
| ---------------------------------------- |
| [ "/home/ryan/.node_libraries" |
| , "/usr/local/lib/node/libraries" |
| ] |
| ---------------------------------------- |
| |
| That is, when +require("mjsunit")+ is called Node looks for |
| |
| 1. +"/home/ryan/.node_libraries/mjsunit.js"+ |
| |
| 2. +"/home/ryan/.node_libraries/mjsunit.node"+ |
| |
| 3. +"/home/ryan/.node_libraries/mjsunit/index.js"+ |
| |
| 4. +"/home/ryan/.node_libraries/mjsunit/index.node"+ |
| |
| 5. +"/usr/local/lib/node/libraries/mjsunit.js"+ |
| |
| 6. +"/usr/local/lib/node/libraries/mjsunit.node"+ |
| |
| 7. +"/usr/local/lib/node/libraries/mjsunit/index.js"+ |
| |
| 8. +"/usr/local/lib/node/libraries/mjsunit/index.node"+ |
| |
| interrupting once a file is found. Files ending in +".node"+ are binary Addon |
| Modules; see the section below about addons. +"index.js"+ allows one to |
| package a module as a directory. |
| |
| +require.paths+ can be modified at runtime by simply unshifting new |
| paths on to it and at startup with the +NODE_PATH+ environmental |
| variable (which should be a list of paths, colon separated). |
| |
| Use +process.mixin()+ to include modules into the global namespace. |
| |
| ---------------------------------------- |
| process.mixin(GLOBAL, require("./circle"), require("sys")); |
| puts("The area of a cirlce of radius 4 is " + area(4)); |
| ---------------------------------------- |
| |
| |
| |
| |
| === Timers |
| |
| |
| +setTimeout(callback, delay)+:: |
| To schedule execution of callback after delay milliseconds. Returns a |
| +timeoutId+ for possible use with +clearTimeout()+. |
| |
| |
| +clearTimeout(timeoutId)+:: |
| Prevents said timeout from triggering. |
| |
| |
| +setInterval(callback, delay)+:: |
| To schedule the repeated execution of callback every +delay+ milliseconds. Returns |
| a +intervalId+ for possible use with +clearInterval()+. |
| |
| |
| +clearInterval(intervalId)+:: |
| Stops a interval from triggering. |
| |
| |
| === Child Processes |
| |
| Node provides a tridirectional +popen(3)+ facility through the class |
| +process.ChildProcess+. It is possible to stream data through the child's +stdin+, |
| +stdout+, and +stderr+ in a fully non-blocking way. |
| |
| ==== +process.ChildProcess+ |
| |
| [cols="1,2,10",options="header"] |
| |========================================================= |
| | Event | Parameters |Notes |
| |
| | +"output"+ | +data+ | Each time the child process |
| sends data to its +stdout+, this event is |
| emitted. +data+ is a string. + If the child |
| process closes its +stdout+ stream (a common |
| thing to do on exit), this event will be emitted |
| with +data === null+. |
| |
| | +"error"+ | +data+ | Identical to the +"output"+ event except for |
| +stderr+ instead of +stdout+. |
| |
| | +"exit"+ | +code+ | This event is emitted after the child process |
| ends. +code+ is the final exit code of the |
| process. One can be assured that after this |
| event is emitted that the +"output"+ and |
| +"error"+ callbacks will no longer be made. |
| |========================================================= |
| |
| +process.createChildProcess(command, args=[], env=ENV)+:: |
| Launches a new process with the given +command+, command line arguments, and |
| environmental variables. For example: |
| + |
| ---------------------------------------- |
| var ls = process.createChildProcess("ls", ["-lh", "/usr"]); |
| ls.addListener("output", function (data) { |
| puts(data); |
| }); |
| ---------------------------------------- |
| + |
| Note, if you just want to buffer the output of a command and return it, then |
| +exec()+ in +/sys.js+ might be better. |
| |
| |
| +child.pid+ :: |
| The PID of the child process. |
| |
| |
| +child.write(data, encoding="ascii")+ :: |
| Write data to the child process's +stdin+. The second argument is optional and |
| specifies the encoding: possible values are +"utf8"+, +"ascii"+, and |
| +"binary"+. |
| |
| |
| +child.close()+ :: |
| Closes the process's +stdin+ stream. |
| |
| |
| +child.kill(signal="SIGTERM")+ :: |
| Send a signal to the child process. If no argument is given, the process |
| will be sent +"SIGTERM"+. See signal(7) for a list of available signals. |
| |
| |
| |
| === POSIX module |
| |
| File I/O is provided by simple wrappers around standard POSIX functions. To |
| use this module do +require("posix")+. |
| |
| All POSIX wrappers have a similar form. They return a promise |
| (+process.Promise+). Example of deleting a file: |
| |
| ------------------------------------------------------------------------------ |
| var posix = require("posix"), |
| sys = require("sys"); |
| |
| var promise = posix.unlink("/tmp/hello"); |
| |
| promise.addCallback(function () { |
| sys.puts("successfully deleted /tmp/hello"); |
| }); |
| ------------------------------------------------------------------------------ |
| |
| There is no guaranteed ordering to the POSIX wrappers. The |
| following is very much prone to error |
| |
| ------------------------------------------------------------------------------ |
| posix.rename("/tmp/hello", "/tmp/world"); |
| posix.stat("/tmp/world").addCallback(function (stats) { |
| sys.puts("stats: " + JSON.stringify(stats)); |
| }); |
| ------------------------------------------------------------------------------ |
| |
| It could be that +stat()+ is executed before the +rename()+. |
| The correct way to do this is to chain the promises. |
| |
| ------------------------------------------------------------------------------ |
| posix.rename("/tmp/hello", "/tmp/world").addCallback(function () { |
| posix.stat("/tmp/world").addCallback(function (stats) { |
| sys.puts("stats: " + JSON.stringify(stats)); |
| }); |
| }); |
| ------------------------------------------------------------------------------ |
| |
| Or use the +promise.wait()+ functionality: |
| |
| ------------------------------------------------------------------------------ |
| posix.rename("/tmp/hello", "/tmp/world").wait(); |
| var stats = posix.stat("/tmp/world").wait(); |
| sys.puts("stats: " + JSON.stringify(stats)); |
| ------------------------------------------------------------------------------ |
| |
| +posix.rename(path1, path2)+ :: |
| See rename(2). |
| - on success: no parameters. |
| - on error: no parameters. |
| |
| |
| |
| +posix.stat(path)+ :: |
| See stat(2). |
| - on success: Returns +posix.Stats+ object. It looks like this: |
| +{ dev: 2049, ino: 305352, mode: 16877, nlink: 12, uid: 1000, gid: 1000, |
| rdev: 0, size: 4096, blksize: 4096, blocks: 8, atime: |
| "2009-06-29T11:11:55Z", mtime: "2009-06-29T11:11:40Z", ctime: |
| "2009-06-29T11:11:40Z" }+ |
| See the +posix.Stats+ section below for more information. |
| - on error: no parameters. |
| |
| +posix.unlink(path)+ :: |
| See unlink(2) |
| - on success: no parameters. |
| - on error: no parameters. |
| |
| |
| +posix.rmdir(path)+ :: |
| See rmdir(2) |
| - on success: no parameters. |
| - on error: no parameters. |
| |
| +posix.mkdir(path, mode)+ :: |
| See mkdir(2) |
| - on success: no parameters. |
| - on error: no parameters. |
| |
| +posix.readdir(path)+ :: |
| Reads the contents of a directory. |
| - on success: One argument, an array containing the names (strings) of the |
| files in the directory (excluding "." and ".."). |
| - on error: no parameters. |
| |
| |
| +posix.close(fd)+ :: |
| See close(2) |
| - on success: no parameters. |
| - on error: no parameters. |
| |
| |
| +posix.open(path, flags, mode)+:: |
| See open(2). The constants like +O_CREAT+ are defined at +process.O_CREAT+. |
| - on success: +fd+ is given as the parameter. |
| - on error: no parameters. |
| |
| |
| +posix.write(fd, data, position, encoding)+:: |
| Write data to the file specified by +fd+. +position+ refers to the offset |
| from the beginning of the file where this data should be written. If |
| +position+ is +null+, the data will be written at the current position. |
| See pwrite(2). |
| - on success: returns an integer +written+ which specifies how many _bytes_ were written. |
| - on error: no parameters. |
| |
| +posix.read(fd, length, position, encoding)+:: |
| |
| Read data from the file specified by +fd+. |
| + |
| +length+ is an integer specifying the number of |
| bytes to read. |
| + |
| +position+ is an integer specifying where to begin |
| reading from in the file. |
| + |
| - on success: returns +data, bytes_read+, what was read from the file. |
| - on error: no parameters. |
| |
| +posix.cat(filename, encoding="utf8")+:: |
| |
| Outputs the entire contents of a file. Example: |
| + |
| -------------------------------- |
| posix.cat("/etc/passwd").addCallback(function (content) { |
| puts(content); |
| }); |
| -------------------------------- |
| + |
| - on success: returns +data+, what was read from the file. |
| - on error: no parameters. |
| |
| ==== +posix.Stats+ |
| |
| Objects returned from +posix.stat()+ are of this type. |
| |
| +stats.isFile()+:: |
| |
| +stats.isDirectory()+:: |
| |
| +stats.isBlockDevice()+:: |
| |
| +stats.isCharacterDevice()+:: |
| |
| +stats.isSymbolicLink()+:: |
| |
| +stats.isFIFO()+:: |
| |
| +stats.isSocket()+:: ... |
| |
| === HTTP |
| |
| To use the HTTP server and client one must +require("http")+. |
| |
| The HTTP interfaces in Node are designed to support many features |
| of the protocol which have been traditionally difficult to use. |
| In particular, large, possibly chunk-encoded, messages. The interface is |
| careful to never buffer entire requests or responses--the |
| user is able to stream data. |
| |
| HTTP message headers are represented by an object like this |
| |
| ---------------------------------------- |
| { "Content-Length": "123" |
| , "Content-Type": "text/plain" |
| , "Connection": "keep-alive" |
| , "Accept": "*/*" |
| } |
| ---------------------------------------- |
| |
| In order to support the full spectrum of possible HTTP applications, Node"s |
| HTTP API is very low-level. It deals with connection handling and message |
| parsing only. It parses a message into headers and body but it does not |
| parse the actual headers or the body. |
| |
| |
| ==== +http.Server+ |
| |
| [cols="1,2,10",options="header"] |
| |========================================================= |
| |Event | Parameters | Notes |
| |
| |+"request"+ | +request, response+ | +request+ is an instance of +http.ServerRequest+ |
| + |
| +response+ is an instance of +http.ServerResponse+ |
| |
| |+"connection"+ | +connection+ | When a new TCP connection is established. |
| +connection+ is an object of type |
| +http.Connection+. Usually users |
| will not want to access this event. |
| The +connection+ can also be |
| accessed at +request.connection+. |
| |
| |+"close"+ | +errorno+ | Emitted when the server closes. +errorno+ |
| is an integer which indicates what, if any, |
| error caused the server to close. If no |
| error occured +errorno+ will be 0. |
| |
| |========================================================= |
| |
| +http.createServer(request_listener, options);+ :: |
| Returns a new web server object. |
| + |
| The +options+ argument is optional. The |
| +options+ argument accepts the same values as the |
| options argument for +tcp.Server+ does. |
| + |
| The +request_listener+ is a function which is automatically |
| added to the +"request"+ event. |
| |
| +server.setSecure(format_type, ca_certs, crl_list, private_key, certificate)+ :: |
| Enable TLS for all incoming connections, with the specified credentials. |
| + |
| format_type currently has to be "X509_PEM", and each of the ca, crl, key and |
| cert parameters are in the format of PEM strings. |
| + |
| The ca_certs is a string that holds a number of CA certificates for use in accepting |
| client connections that authenticate themselves with a client certificate. |
| The private_key is a PEM string of the unencrypted key for the server. |
| |
| +server.listen(port, hostname)+ :: |
| Begin accepting connections on the specified port and hostname. |
| If the hostname is omitted, the server will accept connections |
| directed to any address. This function is synchronous. |
| |
| +server.close()+ :: |
| Stops the server from accepting new connections. |
| |
| |
| |
| ==== +http.ServerRequest+ |
| |
| This object is created internally by a HTTP server--not by |
| the user--and passed as the first argument to a +"request"+ listener. |
| |
| [cols="1,2,10",options="header"] |
| |========================================================= |
| |Event | Parameters | Notes |
| |
| |+"body"+ | +chunk+ | Emitted when a piece of the |
| message body is received. Example: A chunk |
| of the body is given as the single |
| argument. The transfer-encoding has been |
| decoded. The body chunk is a String. The |
| body encoding is set with |
| +request.setBodyEncoding()+. |
| |
| |+"complete"+ | (none) | Emitted exactly once for each message. |
| No arguments. After emitted no other |
| events will be emitted on the request. |
| |========================================================= |
| |
| +request.method+ :: |
| The request method as a string. Read only. Example: |
| +"GET"+, +"DELETE"+. |
| |
| |
| +request.uri+ :: |
| Request URI Object. This contains only the parameters that are |
| present in the actual HTTP request. If the request is |
| + |
| ---------------------------------------- |
| GET /status?name=ryan HTTP/1.1\r\n |
| Accept: text/plain\r\n |
| \r\n |
| ---------------------------------------- |
| + |
| Then +request.uri+ will be |
| + |
| ---------------------------------------- |
| { full: "/status?name=ryan", |
| path: "/status", |
| queryString: "name=ryan", |
| params: { "name": "ryan" }, |
| fragment: "" |
| } |
| ---------------------------------------- |
| |
| |
| +request.headers+ :: |
| Read only. |
| |
| |
| +request.httpVersion+ :: |
| The HTTP protocol version as a string. Read only. Examples: |
| +"1.1"+, +"1.0"+ |
| |
| |
| +request.setBodyEncoding(encoding)+ :: |
| Set the encoding for the request body. Either +"utf8"+ or +"binary"+. Defaults |
| to +"binary"+. |
| |
| |
| +request.pause()+ :: |
| Pauses request from emitting events. Useful to throttle back an upload. |
| |
| |
| +request.resume()+ :: |
| Resumes a paused request. |
| |
| |
| +request.connection+ :: |
| The +http.Connection+ object. |
| |
| |
| ==== +http.ServerResponse+ |
| |
| This object is created internally by a HTTP server--not by the user. It is |
| passed as the second parameter to the +"request"+ event. |
| |
| +response.sendHeader(statusCode, headers)+ :: |
| |
| Sends a response header to the request. The status code is a 3-digit HTTP |
| status code, like +404+. The second argument, +headers+ are the response headers. |
| + |
| Example: |
| + |
| ---------------------------------------- |
| var body = "hello world"; |
| response.sendHeader(200, { |
| "Content-Length": body.length, |
| "Content-Type": "text/plain" |
| }); |
| ---------------------------------------- |
| + |
| This method must only be called once on a message and it must |
| be called before +response.finish()+ is called. |
| |
| +response.sendBody(chunk, encoding="ascii")+ :: |
| |
| This method must be called after +sendHeader+ was |
| called. It sends a chunk of the response body. This method may |
| be called multiple times to provide successive parts of the body. |
| + |
| If +chunk+ is a string, the second parameter |
| specifies how to encode it into a byte stream. By default the |
| +encoding+ is +"ascii"+. |
| + |
| Note: This is the raw HTTP body and has nothing to do with |
| higher-level multi-part body encodings that may be used. |
| + |
| The first time +sendBody+ is called, it will send the buffered header |
| information and the first body to the client. The second time |
| +sendBody+ is called, Node assumes you're going to be streaming data, and |
| sends that seperately. That is, the response is buffered up to the |
| first chunk of body. |
| |
| |
| +response.finish()+ :: |
| This method signals to the server that all of the response headers and body |
| has been sent; that server should consider this message complete. |
| The method, +response.finish()+, MUST be called on each |
| response. |
| |
| |
| |
| ==== +http.Client+ |
| |
| An HTTP client is constructed with a server address as its |
| argument, the returned handle is then used to issue one or more |
| requests. Depending on the server connected to, the client might |
| pipeline the requests or reestablish the connection after each |
| connection. _Currently the implementation does not pipeline requests._ |
| |
| Example of connecting to +google.com+ |
| |
| ---------------------------------------- |
| var sys = require("sys"), |
| http = require("http"); |
| var google = http.createClient(80, "www.google.com"); |
| var request = google.get("/", {"host": "www.google.com"}); |
| request.finish(function (response) { |
| sys.puts("STATUS: " + response.statusCode); |
| sys.puts("HEADERS: " + JSON.stringify(response.headers)); |
| response.setBodyEncoding("utf8"); |
| response.addListener("body", function (chunk) { |
| sys.puts("BODY: " + chunk); |
| }); |
| }); |
| ---------------------------------------- |
| |
| +http.createClient(port, host)+ :: |
| |
| Constructs a new HTTP client. +port+ and |
| +host+ refer to the server to be connected to. A |
| connection is not established until a request is issued. |
| |
| +client.get(path, request_headers)+, +client.head(path, request_headers)+, +client.post(path, request_headers)+, +client.del(path, request_headers)+, +client.put(path, request_headers)+ :: |
| |
| Issues a request; if necessary establishes connection. Returns a +http.ClientRequest+ instance. |
| + |
| +request_headers+ is optional. |
| Additional request headers might be added internally |
| by Node. Returns a +ClientRequest+ object. |
| + |
| Do remember to include the +Content-Length+ header if you |
| plan on sending a body. If you plan on streaming the body, perhaps |
| set +Transfer-Encoding: chunked+. |
| + |
| NOTE: the request is not complete. This method only sends |
| the header of the request. One needs to call |
| +request.finish()+ to finalize the request and retrieve |
| the response. (This sounds convoluted but it provides a chance |
| for the user to stream a body to the server with |
| +request.sendBody()+.) |
| |
| +client.setSecure(format_type, ca_certs, crl_list, private_key, certificate)+ :: |
| Enable TLS for the client connection, with the specified credentials. |
| + |
| format_type currently has to be "X509_PEM", and each of the ca, crl, key and |
| cert parameters are in the format of PEM strings, and optional. |
| + |
| The ca_certs is a string that holds a number of CA certificates for use in deciding the |
| authenticity of the remote server. The private_key is a PEM string of the unencrypted |
| key for the client, which together with the certificate allows the client to authenticate |
| itself to the server. |
| |
| |
| ==== +http.ClientRequest+ |
| |
| This object is created internally and returned from the request methods of a |
| +http.Client+. It represents an _in-progress_ request whose header has |
| already been sent. |
| |
| [cols="1,2,10",options="header"] |
| |========================================================= |
| |Event | Parameters | Notes |
| |+"response"+ | +response+ | |
| Emitted when a response is received to this request. Typically the user will |
| set a listener to this via the +request.finish()+ method. |
| + |
| This event is emitted only once. |
| + |
| The +response+ argument will be an instance of +http.ClientResponse+. |
| |========================================================= |
| |
| |
| +request.sendBody(chunk, encoding="ascii")+ :: |
| |
| Sends a chunk of the body. By calling this method |
| many times, the user can stream a request body to a |
| server—in that case it is suggested to use the |
| +["Transfer-Encoding", "chunked"]+ header line when |
| creating the request. |
| + |
| The +chunk+ argument should be an array of integers |
| or a string. |
| + |
| The +encoding+ argument is optional and only |
| applies when +chunk+ is a string. The encoding |
| argument should be either +"utf8"+ or |
| +"ascii"+. By default the body uses ASCII encoding, |
| as it is faster. |
| |
| |
| +request.finish(responseListener)+ :: |
| |
| Finishes sending the request. If any parts of the body are |
| unsent, it will flush them to the socket. If the request is |
| chunked, this will send the terminating +"0\r\n\r\n"+. |
| + |
| The parameter +responseListener+ is a callback which |
| will be executed when the response headers have been received. |
| The +responseListener+ callback is executed with one |
| argument which is an instance of +http.ClientResponse+. |
| + |
| In the +responseListener+ callback, one can add more listeners to the |
| response, in particular listening for the +"body"+ event. Note that |
| the +responseListener+ is called before any part of the body is receieved, |
| so there is no need to worry about racing to catch the first part of the |
| body. As long as a listener for +"body"+ is added during the |
| +responseListener+ callback, the entire body will be caught. |
| + |
| ---------------------------------------- |
| // Good |
| request.finish(function (response) { |
| response.addListener("body", function (chunk) { |
| puts("BODY: " + chunk); |
| }); |
| }); |
| |
| // Bad - misses all or part of the body |
| request.finish(function (response) { |
| setTimeout(function () { |
| response.addListener("body", function (chunk) { |
| puts("BODY: " + chunk); |
| }); |
| }, 10); |
| }); |
| ---------------------------------------- |
| |
| |
| |
| |
| ==== +http.ClientResponse+ |
| |
| This object is created internally and passed to the +"response"+ event. |
| |
| [cols="1,2,10",options="header"] |
| |========================================================= |
| |Event | Parameters | Notes |
| |
| |+"body"+ | +chunk+ | |
| Emitted when a piece of the message body is received. Example: A chunk of |
| the body is given as the single argument. The transfer-encoding has been |
| decoded. The body chunk a String. The body encoding is set with |
| +response.setBodyEncoding()+. |
| |
| |+"complete"+ | | |
| Emitted exactly once for each message. No arguments. |
| After emitted no other events will be emitted on the response. |
| |
| |========================================================= |
| |
| +response.statusCode+ :: |
| The 3-digit HTTP response status code. E.G. +404+. |
| |
| +response.httpVersion+ :: |
| The HTTP version of the connected-to server. Probably either |
| +"1.1"+ or +"1.0"+. |
| |
| +response.headers+ :: |
| The response headers. |
| |
| +response.setBodyEncoding(encoding)+ :: |
| Set the encoding for the response body. Either +"utf8"+ or +"binary"+. |
| Defaults to +"binary"+. |
| |
| +response.pause()+ :: |
| Pauses response from emitting events. Useful to throttle back a download. |
| |
| +response.resume()+ :: |
| Resumes a paused response. |
| |
| +response.client+ :: |
| A reference to the +http.Client+ that this response belongs to. |
| |
| === Multipart Parsing |
| |
| A library to parse HTTP requests with +multipart/form-data+ is included with |
| Node. To use it, +require("multipart")+. |
| |
| +multipart.parse(options)+ :: |
| - on success: Returns an object where each key holds the value of one part of |
| the stream. +options+ can either be an instance of |
| +http.ServerRequest+ or an object containing a "boundary" and a |
| "data" key. |
| - on error: no parameters. |
| |
| ==== +multipart.Stream+ |
| |
| Here is an example for parsing a +multipart/form-data+ request: |
| |
| ---------------------------------------- |
| var multipart = require("multipart"); |
| var stream = new multipart.Stream(options); |
| var parts = {}; |
| |
| stream.addListener("part", function (part) { |
| var buffer = ""; |
| |
| part.addListener("body", function(chunk) { |
| buffer = buffer + chunk; |
| }); |
| |
| part.addListener("complete", function() { |
| parts[part.name] = buffer; |
| }); |
| }); |
| |
| stream.addListener("complete", function() { |
| // The parts object now contains all parts and data |
| }); |
| ---------------------------------------- |
| |
| |
| [cols="1,2,10",options="header"] |
| |========================================================= |
| |Event | Parameters | Notes |
| |+"part"+ | +part+ | Emitted when a new part is found in the stream. |
| +part+ is an instance of +multipart.Part+. |
| |+"complete"+ | | Emitted when the end of the stream is reached. |
| |========================================================= |
| |
| +stream.bytesTotal+:: |
| The amount of bytes this stream is expected to have. |
| |
| +stream.bytesReceived+:: |
| The amount of bytes received by this stream so far. |
| |
| ==== +multipart.Part+ |
| |
| [cols="1,2,10",options="header"] |
| |========================================================= |
| |Event | Parameters | Notes |
| |+"body"+ | +chunk+ | Emitted when a chunk of body is read. |
| |+"complete"+ | | Emitted when the end of the part is reached. |
| |========================================================= |
| |
| +part.name+:: |
| The field name of this part. |
| |
| +part.filename+:: |
| The filename of this part. Only set for file uploads. |
| |
| === TCP |
| |
| To use the TCP server and client one must +require("tcp")+. |
| |
| ==== +tcp.Server+ |
| |
| Here is an example of a echo server which listens for connections |
| on port 7000 |
| |
| ---------------------------------------- |
| var tcp = require("tcp"); |
| var server = tcp.createServer(function (socket) { |
| socket.setEncoding("utf8"); |
| socket.addListener("connect", function () { |
| socket.send("hello\r\n"); |
| }); |
| socket.addListener("receive", function (data) { |
| socket.send(data); |
| }); |
| socket.addListener("eof", function () { |
| socket.send("goodbye\r\n"); |
| socket.close(); |
| }); |
| }); |
| server.listen(7000, "localhost"); |
| ---------------------------------------- |
| |
| |
| [cols="1,2,10",options="header"] |
| |========================================================= |
| |Event | Parameters | Notes |
| |+"connection"+ | +connection+ | Emitted when a new connection is made. |
| +connection+ is an instance of +tcp.Connection+. |
| |+"close"+ | +errorno+ | Emitted when the server closes. +errorno+ |
| is an integer which indicates what, if any, |
| error caused the server to close. If no |
| error occurred +errorno+ will be 0. |
| |========================================================= |
| |
| +tcp.createServer(connection_listener);+ :: |
| Creates a new TCP server. |
| + |
| The +connection_listener+ argument is automatically set as a listener for |
| the +"connection"+ event. |
| |
| +server.setSecure(format_type, ca_certs, crl_list, private_key, certificate)+ :: |
| Enable TLS for all incoming connections, with the specified credentials. |
| + |
| format_type currently has to be "X509_PEM", and each of the ca, crl, key and |
| cert parameters are in the format of PEM strings. |
| + |
| The ca_certs is a string that holds a number of CA certificates for use in accepting |
| client connections that authenticate themselves with a client certificate. |
| The private_key is a PEM string of the unencrypted key for the server. |
| |
| +server.listen(port, host=null, backlog=128)+ :: |
| Tells the server to listen for TCP connections to +port+ and +host+. |
| + |
| +host+ is optional. If +host+ is not specified the server will accept client |
| connections on any network address. |
| + |
| The third argument, +backlog+, is also optional and defaults to 128. The |
| +backlog+ argument defines the maximum length to which the queue of pending |
| connections for the server may grow. |
| + |
| This function is synchronous. |
| |
| +server.close()+:: |
| Stops the server from accepting new connections. This function is |
| asynchronous, the server is finally closed when the server emits a +"close"+ |
| event. |
| |
| |
| ==== +tcp.Connection+ |
| |
| This object is used as a TCP client and also as a server-side |
| socket for +tcp.Server+. |
| |
| [cols="1,2,10",options="header"] |
| |========================================================= |
| |Event | Parameters | Notes |
| |+"connect"+ | | Call once the connection is established |
| after a call to +createConnection()+ or |
| +connect()+. |
| |+"receive"+ | +data+ | Called when data is received on the |
| connection. +data+ will be a string. |
| Encoding of data is set by |
| +connection.setEncoding()+. |
| |+"eof"+ | | Called when the other end of the |
| connection sends a FIN packet. |
| After this is emitted the +readyState+ |
| will be +"writeOnly"+. One should probably |
| just call +connection.close()+ when this |
| event is emitted. |
| |+"timeout"+ | | Emitted if the connection times out from |
| inactivity. The +"close"+ event will be |
| emitted immediately following this event. |
| |+"drain"+ | | Emitted when the write buffer becomes |
| empty. Can be used to throttle uploads. |
| |+"close"+ | +had_error+ | Emitted once the connection is fully |
| closed. The argument +had_error+ |
| is a boolean which says if the connection |
| was closed due to a transmission error. |
| (TODO: access error codes.) |
| |========================================================= |
| |
| +tcp.createConnection(port, host="127.0.0.1")+:: |
| Creates a new connection object and opens a connection to the specified |
| +port+ and +host+. If the second parameter is omitted, localhost is assumed. |
| + |
| When the connection is established the +"connect"+ event will be emitted. |
| |
| +connection.connect(port, host="127.0.0.1")+:: |
| Opens a connection to the specified +port+ and +host+. +createConnection()+ |
| also opens a connection; normally this method is not needed. Use this only |
| if a connection is closed and you want to reuse the object to connect to |
| another server. |
| + |
| This function is asynchronous. When the +"connect"+ event is emitted the |
| connection is established. If there is a problem connecting, the +"connect"+ |
| event will not be emitted, the +"close"+ event will be emitted with |
| +had_error == true+. |
| |
| +connection.remoteAddress+:: |
| The string representation of the remote IP address. For example, |
| +"74.125.127.100"+ or +"2001:4860:a005::68"+. |
| + |
| This member is only present in server-side connections. |
| |
| |
| +connection.readyState+:: |
| Either +"closed"+, +"open"+, +"opening"+, +"readOnly"+, or +"writeOnly"+. |
| |
| |
| +connection.setEncoding(encoding)+:: |
| Sets the encoding (either +"ascii"+, +"utf8"+, or +"binary"+) for data that is received. |
| |
| +connection.send(data, encoding="ascii")+:: |
| Sends data on the connection. The second parameter specifies the encoding |
| in the case of a string--it defaults to ASCII because encoding to UTF8 is |
| rather slow. |
| |
| |
| +connection.close()+:: |
| Half-closes the connection. I.E., it sends a FIN packet. It is |
| possible the server will still send some data. After calling |
| this +readyState+ will be +"readOnly"+. |
| |
| |
| +connection.forceClose()+:: |
| Ensures that no more I/O activity happens on this socket. Only |
| necessary in case of errors (parse error or so). |
| |
| +connection.readPause()+:: |
| Pauses the reading of data. That is, +"receive"+ events will not be emitted. |
| Useful to throttle back an upload. |
| |
| +connection.readResume()+:: |
| Resumes reading if reading was paused by +readPause()+. |
| |
| +connection.setTimeout(timeout)+:: |
| Sets the connection to timeout after +timeout+ milliseconds of inactivity on |
| the connection. By default all +tcp.Connection+ objects have a timeout |
| of 60 seconds (60000 ms). |
| + |
| If +timeout+ is 0, then the idle timeout is disabled. |
| |
| +connection.setNoDelay(noDelay=true)+:: |
| Disables the Nagle algorithm. By default TCP connections use the Nagle |
| algorithm, they buffer data before sending it off. Setting +noDelay+ will |
| immediately fire off data each time +connection.send()+ is called. |
| |
| +connection.verifyPeer()+:: |
| Returns an integer indicating the trusted status of the peer in a TLS |
| connection. |
| + |
| Returns 1 if the peer's certificate is issued by one of the trusted CAs, |
| the certificate has not been revoked, is in the issued date range, |
| and if the peer is the server, matches the hostname. |
| + |
| Returns 0 if no certificate was presented by the peer, or negative result |
| if the verification fails (with a given reason code). This function is synchronous. |
| |
| +connection.getPeerCertificate(format)+:: |
| For a TLS connection, returns the peer's certificate information, as defined |
| by the given format. |
| + |
| A format of "DNstring" gives a single string with the combined Distinguished |
| Name (DN) from the certificate, as comma delimited name=value pairs as defined |
| in RFC2253. This function is synchronous. |
| |
| === DNS module |
| |
| Use +require("dns")+ to access this module |
| |
| Here is an example of which resolves +"www.google.com"+ then reverse |
| resolves the IP addresses which are returned. |
| |
| ------------------------------------------------------------------------- |
| var dns = require("dns"); |
| |
| var resolution = dns.resolve4("www.google.com"); |
| |
| resolution.addCallback(function (addresses, ttl, cname) { |
| puts("addresses: " + JSON.stringify(addresses)); |
| puts("ttl: " + JSON.stringify(ttl)); |
| puts("cname: " + JSON.stringify(cname)); |
| |
| for (var i = 0; i < addresses.length; i++) { |
| var a = addresses[i]; |
| var reversing = dns.reverse(a); |
| reversing.addCallback( function (domains, ttl, cname) { |
| puts("reverse for " + a + ": " + JSON.stringify(domains)); |
| }); |
| reversing.addErrback( function (code, msg) { |
| puts("reverse for " + a + " failed: " + msg); |
| }); |
| } |
| }); |
| |
| resolution.addErrback(function (code, msg) { |
| puts("error: " + msg); |
| }); |
| ------------------------------------------------------------------------- |
| |
| |
| +dns.resolve4(domain)+:: |
| |
| Resolves a domain (e.g. +"google.com"+) into an array of IPv4 addresses (e.g. |
| +["74.125.79.104", "74.125.79.105", "74.125.79.106"]+). |
| This function returns a promise. |
| - on success: returns +addresses, ttl, cname+. +ttl+ (time-to-live) is an integer |
| specifying the number of seconds this result is valid for. +cname+ is the |
| canonical name for the query. |
| - on error: returns +code, msg+. +code+ is one of the error codes listed |
| below and +msg+ is a string describing the error in English. |
| |
| +dns.resolve6(domain)+:: |
| |
| The same as +dns.resolve4()+ except for IPv6 queries (an +AAAA+ query). |
| |
| +dns.reverse(ip)+:: |
| |
| Reverse resolves an ip address to an array of domain names. |
| |
| - on success: returns +domains, ttl, cname+. +ttl+ (time-to-live) is an integer |
| specifying the number of seconds this result is valid for. +cname+ is the |
| canonical name for the query. +domains+ is an array of domains. |
| - on error: returns +code, msg+. +code+ is one of the error codes listed |
| below and +msg+ is a string describing the error in English. |
| |
| |
| Each DNS query can return an error code. |
| |
| - +dns.TEMPFAIL+: timeout, SERVFAIL or similar. |
| - +dns.PROTOCOL+: got garbled reply. |
| - +dns.NXDOMAIN+: domain does not exists. |
| - +dns.NODATA+: domain exists but no data of reqd type. |
| - +dns.NOMEM+: out of memory while processing. |
| - +dns.BADQUERY+: the query is malformed. |
| |
| |
| |
| == REPL |
| |
| A Read-Eval-Print-Loop is available both as a standalone program and easily |
| includable in other programs. |
| |
| The standalone REPL is called +node-repl+ and is installed at |
| +$PREFIX/bin/node-repl+. It's recommended to use it with the program |
| +rlwrap+ for a better user interface. I set |
| ------------------------------------ |
| alias node-repl="rlwrap node-repl" |
| ------------------------------------ |
| in my zsh configuration. |
| |
| Inside the REPL, Control+D will exit. The special variable +_+ (underscore) contains the |
| result of the last expression. |
| |
| The library is called +/repl.js+ and it can be used like this: |
| ------------------------------------ |
| var sys = require("sys"), |
| tcp = require("tcp"), |
| repl = require("repl"); |
| nconnections = 0; |
| tcp.createServer(function (c) { |
| sys.error("Connection!"); |
| nconnections += 1; |
| c.close(); |
| }).listen(5000); |
| repl.start("simple tcp server> "); |
| ------------------------------------ |
| The repl provides access to any variables in the global scope. You can expose a variable |
| to the repl explicitly by assigning it to the +repl.scope+ object: |
| ------------------------------------ |
| var count = 5; |
| repl.start(); |
| repl.scope.count = count; |
| ------------------------------------ |
| |
| == Addons |
| |
| Addons are dynamically linked shared objects. They can provide glue to C and |
| C++ libraries. The API (at the moment) is rather complex, involving |
| knowledge of several libraries: |
| |
| - V8 Javascript, a C++ library. Used for interfacing with Javascript: |
| creating objects, calling functions, etc. Documented mostly in the |
| +v8.h+ header file (+deps/v8/include/v8.h+ in the Node source tree). |
| |
| - libev, C event loop library. Anytime one needs to wait for a file |
| descriptor to become readable, wait for a timer, or wait for a signal to |
| received one will need to interface with libev. That is, if you perform |
| any I/O, libev will need to be used. Node uses the +EV_DEFAULT+ event |
| loop. Documentation can be found http:/cvs.schmorp.de/libev/ev.html[here]. |
| |
| - libeio, C thread pool library. Used to execute blocking POSIX system |
| calls asynchronously. Mostly wrappers already exist for such calls, in |
| +src/file.cc+ so you will probably not need to use it. If you do need it, |
| look at the header file +deps/libeio/eio.h+. |
| |
| - Internal Node libraries. Most importantly is the +node::EventEmitter+ |
| class which you will likely want to derive from. |
| |
| - Others. Look in +deps/+ for what else is available. |
| |
| Node statically compiles all its dependencies into the executable. When |
| compiling your module, you don't need to worry about linking to any of these |
| libraries. |
| |
| To get started let's make a small Addon which does the following except in |
| C++: |
| ----------------------------------------------------- |
| exports.hello = "world"; |
| ----------------------------------------------------- |
| |
| To get started we create a file +hello.cc+: |
| ----------------------------------------------------- |
| #include <v8.h> |
| |
| using namespace v8; |
| |
| extern "C" void |
| init (Handle<Object> target) |
| { |
| HandleScope scope; |
| target->Set(String::New("hello"), String::New("World")); |
| } |
| ----------------------------------------------------- |
| |
| This source code needs to be built into +hello.node+, the binary Addon. To |
| do this we create a file called +wscript+ which is python code and looks |
| like this: |
| ----------------------------------------------------- |
| srcdir = "." |
| blddir = "build" |
| VERSION = "0.0.1" |
| |
| def set_options(opt): |
| opt.tool_options("compiler_cxx") |
| |
| def configure(conf): |
| conf.check_tool("compiler_cxx") |
| conf.check_tool("node_addon") |
| |
| def build(bld): |
| obj = bld.new_task_gen("cxx", "shlib", "node_addon") |
| obj.target = "hello" |
| obj.source = "hello.cc" |
| ----------------------------------------------------- |
| Running +node-waf configure build+ will create a file |
| +build/default/hello.node+ which is our Addon. |
| |
| +node-waf+ is just http://code.google.com/p/waf/[WAF], the python-based build system. +node-waf+ is |
| provided for the ease of users. |
| |
| All Node addons must export a function called +init+ with this signature: |
| ----------------------------------------------------- |
| extern "C" void init (Handle<Object> target) |
| ----------------------------------------------------- |
| |
| For the moment, that is all the documentation on addons. Please see |
| http://github.com/ry/node_postgres[node_postgres] for a real example. |
| |
| // vim: set syntax=asciidoc: |