Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Save more on your purchases! discount-offer-chevron-icon
Savings automatically calculated. No voucher code required.
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Newsletter Hub
Free Learning
Arrow right icon
timer SALE ENDS IN
0 Days
:
00 Hours
:
00 Minutes
:
00 Seconds
Mastering Node.js
Mastering Node.js

Mastering Node.js: Expert techniques for building fast servers and scalable, real-time network applications with minimal effort

eBook
€28.99 €32.99
Paperback
€41.99
Subscription
Free Trial
Renews at €18.99p/m

What do you get with Print?

Product feature icon Instant access to your digital copy whilst your Print order is Shipped
Product feature icon Paperback book shipped to your preferred address
Product feature icon Redeem a companion digital copy on all Print orders
Product feature icon Access this title in our online reader with advanced features
Product feature icon DRM FREE - Read whenever, wherever and however you want
OR
Modal Close icon
Payment Processing...
tick Completed

Shipping Address

Billing Address

Shipping Methods
Table of content icon View table of contents Preview book icon Preview Book

Mastering Node.js

Chapter 1. Understanding the Node Environment

 

Node's goal is to provide an easy way to build scalable network programs.

 
 --Ryan Dahl, creator of Node.js

The WWW (World Wide Web) makes it possible for hypermedia objects on the Internet to interconnect, communicating through a standard set of Internet protocols, commonly HTTP (Hyper Text Transfer Protocol). The growth in the complexity, number, and type of web applications delivering curated collections of these objects through the browser has increased interest in technologies that aid in the construction and management of intricate networked applications. Node is one such technology. By mastering Node you are learning how to build the next generation of software.

The hold that any one person has on information is tenuous. Complexity follows scale; confusion follows complexity. As resolution blurs, errors happen.

Similarly, the activity graph describing all expected I/O (Input/Output) interactions an application may potentially form between clients and providers must be carefully planned and managed, lest the capacity of both the system and its creator be overwhelmed. This involves controlling two dimensions of information: volume and shape.

As a network application scales, the volume of information it must recognize, organize, and maintain increases. This volume, in terms of I/O streams, memory usage, and CPU (Central Processing Unit) load, expands as more clients connect, and even as they leave (in terms of persisting user-specific data).

This expansion of information volume also burdens the application developer, or team of developers. Scaling issues begin to present themselves, usually demonstrating a failure to accurately predict the behavior of large systems from the behavior of small systems. Can a data layer designed for storing a few thousand records accommodate a few million? Are the algorithms used to search a handful of records efficient enough to search many more? Can this server handle 10,000 simultaneous client connections? The edge of innovation is sharp and cuts quickly, presenting less time for deliberation precisely when the cost of error is being magnified. The shape of objects comprising the whole of an application becomes amorphous and difficult to understand, particularly as ad hoc modifications are made, reactively, in response to dynamic tension in the system. What is described in a specification as a small subsystem may have been patched into so many other systems that its actual boundaries are misunderstood. It becomes impossible to accurately trace the outline of the composite parts of the whole.

Eventually an application becomes unpredictable. It is dangerous when one cannot predict all future states of an application, or the side effects of change. Any number of servers, programming languages, hardware architectures, management styles, and so on, have attempted to subdue the intractable problem of risk following growth, of failure menacing success. Oftentimes systems of even greater complexity are sold as the cure.

Node chose clarity and simplicity instead. There is one thread, bound to an event loop. Deferred tasks are encapsulated, entering and exiting the execution context via callbacks. I/O operations generate evented data streams, these piped through a single stack. Concurrency is managed by the system, abstracting away thread pools and simplifying memory management. Dependencies and libraries are introduced through a package management system, neatly encapsulated, and easy to distribute, install, and invoke.

Experienced developers have all struggled with the problems that Node aims to solve:

  • How to serve many thousands of simultaneous clients efficiently
  • Scaling networked applications beyond a single server
  • Preventing I/O operations from becoming bottlenecks
  • Eliminating single points of failure, thereby ensuring reliability
  • Achieving parallelism safely and predictably

As each year passes, we see collaborative applications and software responsible for managing levels of concurrency that would have been considered rare just a few years ago. Managing concurrency, both in terms of connection handling and application design, is the key to building scalable web architectures.

In this book we will study the techniques professional Node developers use to tackle these problems. In this chapter, we will explore how a Node application is designed, the shape and texture of its footprint on a server, and the powerful base set of tools and features Node provides for developers. Throughout we will examine progressively more intricate examples demonstrating how Node's simple, comprehensive, and consistent architecture solves many difficult problems well.

Extending JavaScript

When he designed Node, JavaScript was not Ryan Dahl's original language choice. Yet, after exploring it, he found a very good modern language without opinions on streams, the filesystem, handling binary objects, processes, networking, and other capabilities one would expect to exist in a system's programming language. JavaScript, strictly limited to the browser, had no use for, and had not implemented, these features.

Dahl was guided by a few rigid principles:

  • A Node program/process runs on a single thread, ordering execution through an event loop
  • Web applications are I/O intensive, so the focus should be on making I/O fast
  • Program flow is always directed through asynchronous callbacks
  • Expensive CPU operations should be split off into separate parallel processes, emitting events as results arrive
  • Complex programs should be assembled from simpler programs

The general principle is, operations must never block. Node's desire for speed (high concurrency) and efficiency (minimal resource usage) demands the reduction of waste. A waiting process is a wasteful process, especially when waiting for I/O.

JavaScript's asynchronous, event-driven design fits neatly into this model. Applications express interest in some future event and are notified when that event occurs. This common JavaScript pattern should be familiar to you:

Window.onload = function() {
  // When all requested document resources are loaded, 
  // do something with the resulting environment 
}

element.onclick = function() {
  // Do something when the user clicks on this element
}

The time it will take for an I/O action to complete is unknown, so the pattern is to ask for notification when an I/O event is emitted, whenever that may be, allowing other operations to be completed in the meantime.

Node adds an enormous amount of new functionality to JavaScript. Primarily, the additions provide evented I/O libraries offering the developer system access not available to browser-based JavaScript, such as writing to the filesystem or opening another system process. Additionally, the environment is designed to be modular, allowing complex programs to be assembled out of smaller and simpler components.

Let's look at how Node imported JavaScript's event model, extended it, and used it in the creation of interfaces to powerful system commands.

Events

Many of the JavaScript extensions in Node emit events. These events are instances of events.EventEmitter. Any object can extend EventEmitter, providing the developer with an elegant toolkit for building tight asynchronous interfaces to object methods.

Work through this example demonstrating how to set an EventEmitter object as the prototype of a function constructor. As each constructed instance now has the EventEmitter object exposed to its prototype chain, this provides a natural reference to the event API (Application Programming Interface). The counter instance methods can therefore emit events, and these can be listened for. Here we emit the latest count whenever the counter.increment method is called, and bind a callback to the incremented event, which simply prints the current counter value to the command line:

var EventEmitter = require('events').EventEmitter;
var Counter = function(init) {
  this.increment = function() {
      init++; 
      this.emit('incremented', init);
  }
}
Counter.prototype = new EventEmitter();
var counter = new Counter(10);
var callback = function(count) {
    console.log(count);
}
counter.addListener('incremented', callback);

counter.increment(); // 11
counter.increment(); // 12

To remove the event listeners bound to counter, use counter.removeListener('incremented', callback). For consistency with browser-based JavaScript, counter.on and counter.addListener are interchangeable.

The addition of EventEmitter as an extensible object greatly increases the possibilities of JavaScript on the server. In particular, it allows I/O data streams to be handled in an event-oriented manner, in keeping with the Node's principle of asynchronous, non-blocking programming:

var Readable = require('stream').Readable;
var readable = new Readable;
var count = 0;

readable._read = function() {
  if(++count > 10) {
    return readable.push(null);
  }
  setTimeout(function() {
    readable.push(count + "\n");
  }, 500);
};
readable.pipe(process.stdout);

In this program we are creating a Readable stream and piping any data pushed into this stream to process.stdout. Every 500 milliseconds we increment a counter and push that number (adding a newline) onto the stream, resulting in an incrementing series of numbers being written to the terminal. When our series has reached its limit (10), we push null onto the stream, causing it to terminate. Don't worry if you don't fully understand how Readable is implemented here—streams will be fully explained in the following chapters. Simply note how the act of pushing data onto a stream causes a corresponding event to fire, how the developer can assign a custom callback to handle this event, and how newly added data can be redirected to other streams. Node is designed such that I/O operations are consistently implemented as asynchronous, evented data streams.

It is also important to note the importance of this style of I/O. Because Node's event loop need only commit resources to handling callbacks, many other instructions can be processed in the down time between each interval.

As an exercise, re-implement the previous code snippet such that the emitted data is piped to a file. You'll need to use fs.createWriteStream:

var fs = require('fs');
var writeStream = fs.createWriteStream("./counter", {
  flags : 'w',
  mode: 0666
});

Modularity

In his book The Art of Unix Programming, Eric Raymond proposed the Rule of Modularity:

Developers should build a program out of simple parts connected by well defined interfaces, so problems are local, and parts of the program can be replaced in future versions to support new features. This rule aims to save time on debugging complex code that is complex, long, and unreadable.

This idea of building complex systems out of small pieces, loosely joined is seen in the management theory, theories of government, physical manufacturing, and many other contexts. In terms of software development, it advises developers to contribute only the simplest and most useful component necessary within a larger system. Large systems are hard to reason about, especially if the boundaries of its components are fuzzy.

One of the primary difficulties when constructing scalable JavaScript programs is the lack of a standard interface for assembling a coherent program out of many smaller ones. For example, a typical web application might load dependencies using a sequence of <script> tags in the <head> section of an HTML document:

<head>
<script src="fileA.js"></script>
<script src="fileB.js"></script>
</head>

There are many problems with this sort of solution:

  1. All potential dependencies must be declared prior to being needed—dynamic inclusion requires complicated hacks.
  2. The introduced scripts are not forcibly encapsulated—nothing stops code in both files from writing to the same global object. Namespaces can easily collide, making arbitrary injection dangerous.
  3. fileA cannot address fileB as a collection—an addressable context such as fileB.method isn't available.
  4. The <script> method itself isn't systematic, precluding the design of useful module services, such as dependency awareness or version control.
  5. Scripts cannot be easily removed, or overridden.
  6. Because of these dangers and difficulties, sharing is not effortless, diminishing opportunities for collaboration in an open ecosystem.

Ambivalently inserting unpredictable code fragments into an application frustrates attempts to predictably shape functionality. What is needed is a standard way to load and share discreet program modules.

Accordingly, Node introduced the concept of the package, following the CommonJS specification. A package is a collection of program files bundled with a manifest file describing the collection. Dependencies, authorship, purpose, structure, and other important meta-data are exposed in a standard way. This encourages the construction of large systems from many small, interdependent systems. Perhaps even more importantly, it encourages sharing:

 

What I'm describing here is not a technical problem. It's a matter of people getting together and making a decision to step forward and start building up something bigger and cooler together.

 
 --Kevin Dangoor, creator of CommonJS

In many ways the success of Node is due to growth in the number and quality of packages available to the developer community, distributed via Node's package management system, npm. The design choices of this system, both social and technical, have done much to help make JavaScript a viable professional option for systems programming.

More extensive information on creating and managing Node packages can be found in Appendix A, Organizing Your Work. The key point is this: build programs out of packages where possible, and share those packages when possible. The shape of your applications will be clearer and easier to maintain. Importantly, the efforts of thousands of other developers can be linked into applications via npm, directly by inclusion, and indirectly as shared packages are tested, improved, refactored, and repurposed by members of the Node community.

Note

Contrary to popular belief, npm is not an abbreviation for Node Package Manager (or even an acronym):

https://npmjs.org/doc/faq.html#If-npm-is-an-acronym-why-is-it-never-capitalized

The Network

I/O in the browser is mercilessly hobbled, for very good reasons—if the JavaScript on any given website could access your filesystem, or open up network connections to any server, the WWW would be a less fun place.

For Node, I/O is of fundamental importance, and its focus from the start was to simplify the creation of scalable systems with high I/O requirements. It is likely that your first experience with Node was in writing an HTTP server.

Node supports several standard network protocols in addition to HTTP, such as TLS/SSL (Transport Layer Security/Secure Sockets Layer), and UDP (User Datagram Protocol). With these tools we can easily build scalable network programs, moving well beyond the somewhat dated AJAX (Asynchronous JavaScript And Xml) techniques familiar to the JavaScript developer.

Let's create a simple program that allows the user to send data between two UDP servers:

var dgram = require('dgram');
var client = dgram.createSocket("udp4");
var server = dgram.createSocket("udp4");

var message = process.argv[2] || "message";

message = new Buffer(message);

server
.on("message", function (msg) {
  process.stdout.write("Got message: " + msg + "\n");
  process.exit();
  
})
.bind(41234);

client.send(message, 0, message.length, 41234, "localhost");

Assuming a program file name of udp.js a message can be sent via UDP by running this program from the terminal like so:

node udp.js "my message"

Which will result in the following output:

Got message: my message

We first establish our UDP servers, one working as a broadcaster, the other as a listener. process.argv contains useful command information, including command-line arguments commencing at index(2), which in this case would contain "my message". UDP requires messages to be Buffer objects, so we ensure that some message exists and convert it.

A UDP server is an instance of EventEmitter, emitting a message event when messages are received on the port it is bound. This server simply echoes the received message. All that is left to do is send the message, which action is performed by the client, passing along our message to port #41234.

Moving streams of data around the I/O layer of your application is simplified within Node. It isn't difficult to share data streams across differing protocol servers, as data streams are standardized via Node's interfaces. Protocol details are handled for you.

Let's continue to explore I/O, the process object, and events. First, let's dig into the machine powering Node's core.

V8

V8 is Google's JavaScript engine, written in C++. It compiles and executes JavaScript code inside of a VM (Virtual Machine). When a webpage loaded into Google Chrome demonstrates some sort of dynamic effect, like automatically updating a list or news feed, you are seeing JavaScript, compiled by V8, at work.

While Node itself will efficiently manage I/O operations, its process object refers to the V8 runtime. As such, it is important to understand how to configure the V8 environment, especially as your application grows in size.

By typing node -h into a console, something like the following will be displayed:

V8

We can see how a list of V8 options is accessible via the –-v8-options flag.

The list of configuration options for V8 is a long one, so we're not going to cover each option here. As we progress through the book, relevant options will be discussed with more depth. It is nevertheless useful to summarize some of the options provided for managing system limits and memory, as well as those used to configure JavaScript's command set, introducing some of the new features in ES6 (EcmaScript6), often referred to as Harmony.

The version of V8 used by your Node installation can be viewed by typing:

node –e "console.log(process.versions.v8)"

Memory and other limits

One very powerful V8 configuration option is important enough to make it into Node's own collection: --max-stack-size. Let's look into some of the new powers a Node developer has been given in being able to configure a specific JavaScript runtime.

Trying to break a system is an excellent way to discover its limits and shape. Let's write a program that will crash V8:

var count = 0;
(function curse() { 
  console.log(++count);
  curse();
})()

This self-contained, self-executing function will recursively call itself forever, or until it is forced to stop. Each iteration of curse adds another frame to the call stack. This uncontrolled growth will eventually cause the JavaScript runtime to collapse, citing a RangeError: Maximum call stack size exceeded.

The purpose of --max-stack-size should now be clear. The direct V8 option equivalent is –-stack_size, which is passed a value, in KB (Kilobytes), to raise this limit. Experiment with the above program, noting the number of iterations possible at different settings.

While it is likely that hitting this limit represents an incorrectly designed algorithm, being able to expand the width of the operating space available to a Node process adds to the collection of solutions available to developers.

On 32 bit and 64 bit machines V8's memory allocation defaults are, respectively, 700 MB and 1400 MB. In newer versions of V8, memory limits on 64 bit systems are no longer set by V8, theoretically indicating no limit. However, the OS (Operating System) on which Node is running can always limit the amount of memory V8 can take, so the true limit of any given process cannot be generally stated.

V8 makes available the --max_old_space_size option, which allows control over the amount of memory available to a process, accepting a value in MB. Should you need to increase memory allocation, simply pass this option the desired value when spawning a Node process.

It is often an excellent strategy to reduce the available memory allocation for a given Node instance, especially when running many instances. As with stack limits, consider whether massive memory needs are better delegated to a dedicated storage layer, such as an in-memory database or similar.

Note

An informative discussion with the V8 team regarding their views on how memory should be allocated can be found here:

http://code.google.com/p/v8/issues/detail?id=847

One of the key advantages of modern high-level languages such as JavaScript is the automatic management of memory through GC (Garbage Collection). GC strategies are many and complex, yet all follow a simple core idea: every so often, free allocated memory that is no longer being used.

The drawback of automatic GC is that it puts a slight brake on process speed. While the clear advantages of automatic GC outweigh its drawbacks in the majority of cases, there remains for the Node developer an opportunity to control some of its behavior. This is primarily done via the flags –-nouse_idle_notification and –-expose_gc.

Passing the –-nouse_idle_notification flag will tell V8 to ignore idle notification calls from Node, which are requests to V8 asking it to run GC immediately, as the Node process is currently idle. Because Node is aggressive with these calls (efficiency breeds clean slates), an excess of GC may slow down your application. Note that using this flag does not disable GC; GC simply runs less often. In the right circumstances this technique can increase performance.

--expose_gc introduces a new global method to the Node process, gc(), which allows JavaScript code to manually start the GC process. In conjunction with –-nouse_idle_notification the developer can now control to some degree how often GC runs. At any point in my JavaScript code I can simply call gc() and start the collector.

Being able to adjust memory usage and GC is certainly useful. Remember that application volume can rapidly rise in unpredictable ways. If the memory footprint of your application holds steady near the very limits of V8's allocation, you should begin to think about scaling horizontally. Use memory wisely, and split off new Node instances where appropriate.

Harmony

JavaScript has never stopped evolving and it is now experiencing something of a renaissance, helped in no small part by the popularity of Node. The language's next version, named Harmony, introduces some significant new features and concepts.

Note

More information on ES6 Harmony can be found at: http://wiki.ecmascript.org/doku.php?id=harmony:harmony.

The available Harmony options are:

Flag

Description

--harmony_typeof

Enable semantics for typeof

--harmony_scoping

Enable block scoping

--harmony_modules

Enable modules (implies block scoping)

--harmony_proxies

Enable proxies

--harmony_collections

Enable collections (sets, maps, and weak maps)

--harmony

Enable all features (except typeof)

It is beyond the scope of this book to discuss these new features in any depth. Nonetheless, it should be stated that this ability to use the very latest JavaScript features, now, through Node, offers the developer a great advantage—there is no browser war on a server to hold back innovation.

For example, ES6's weakMap allows the use of non-strings as keys in a HashMap:

"use strict"
let owners = new WeakMap();
let task = {
  title 	: "Big Project"
};
owners.set(task, 'John');
function owner(task) {
  if(owners.has(task)) {
    return console.log(owners.get(task));
  }
  console.log("No owner for this task.");
}
owner(task);   // "John"
owner({});   // "No owner for this task"

As an exercise, the reader might map (fixed) input streams to (variable) output streams in a similar manner.

The process object

By now it should be clear as to how Node is structured, in terms of V8, the event loop, and so forth. We are now going to discuss, in detail, how instructions that you write (a JavaScript program) are compiled by V8 into a list of instructions whose execution context is accessible via the native Node process object.

The single thread forming the spine of Node's event loop is V8's event loop. When I/O operations are initiated within this loop they are delegated to libuv, which manages the request using its own (multi-threaded, asynchronous) environment. libuv announces the completion of I/O operations, allowing any callbacks waiting on this event to be re-introduced to the main V8 thread for execution:

The process object

Node's process object provides information on and control over the current running process. It is an instance of EventEmitter, is accessible from any scope, and exposes very useful low-level pointers. Consider the following program:

var size = process.argv[2];
var totl = process.argv[3] || 100;
var buff = [];
for(var i=0; i < totl; i++) {
  buff.push(new Buffer(size));
  process.stdout.write(process.memoryUsage().heapTotal + "\n");
}

Tip

Downloading the example code:

You can download the example code files for all Packt books you have purchased from your account at http://www.packtpub.com. If you purchased this book elsewhere, you can visit http://www.packtpub.com/support and register to have the files e-mailed directly to you.

Assuming the program file is named process.js, it would be executed like so:

> node process.js 1000000 100

This execution context first fetches the two command-line arguments via process.argv, builds a looping construct that grows memory usage depending on these arguments, and emits memory usage data as each new allocation is made. The program sends output to stdout, but could alternatively stream output to other processes, or even a file:

> node process.js 1000000 100 > out.file

In fact, the familiar console.log is implemented in the Node core as a wrapper around process.stdout.write:

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

A Node process begins by constructing a single execution stack, with the global context forming the base of the stack. Functions on this stack execute within their own, local, context (sometimes referred to as scope), which remains enclosed within the global context (which you'll hear referred to as closure). Because Node is evented, any given execution context can commit the running thread to handling an eventual execution context. This is the purpose of callback functions.

Consider the following schematic of a simple interface for accessing the filesystem:

The process object

If we were to instantiate Filesystem and call readDir a nested execution context structure would be created: (global (fileSystem (readDir (anonymous function) ) ) ). The concomitant execution stack is introduced to Node's single process thread. This stack remains in memory until libuv reports that fs.readdir has completed, at which point the registered anonymous callback fires, resolving the sole pending execution context. As no further events are pending, and the maintenance of closures no longer necessary, the entire structure can be safely torn down (in reverse, beginning with anonymous), and the process can exit, freeing any allocated memory. This method of building up and tearing down a single stack is what Node's event loop is ultimately doing.

We'll explore the full suite of commands and attributes contained by the process object as we continue to develop examples and libraries in this book.

The Read-Eval-Print Loop and executing a Node program

Node's REPL (Read-Eval-Print-Loop) represents the Node shell. To enter the shell prompt, enter Node via your terminal without passing a filename:

> node

You now have access to a running Node process, and may pass JavaScript commands to this process. For example, after entering 2+2 the shell would send 4 to stdout. Node's REPL is an excellent place to try out, debug, test, or otherwise play with JavaScript code.

Because the REPL is a native object, programs can also use instances as a context in which to run JavaScript interactively. For example, here we create our own custom function sayHello, add it to the context of a REPL instance, and start the REPL, emulating a Node shell prompt:

require('repl').start("> ").context.sayHello = function() {
    return "Hello"
};

Entering sayHello() at the prompt will result in Hello being sent to stdout.

Let's take everything we've learned in this chapter and create an interactive REPL which allows us to execute JavaScript on a remote server.

Create two files, repl_client.js and repl_server.js, using the following code, and run each in its own terminal window, such that both terminal windows are visible to you.

/*	repl_client.js   */
var net = require('net');
var sock = net.connect(8080);
process.stdin.pipe(sock);
sock.pipe(process.stdout);

/*	repl_server.js  */
var repl = require('repl')
var net = require('net')
net.createServer(function(socket) {
  repl
  .start({
    prompt : '> ',
    input    : socket,
    output  : socket,
    terminal  : true
  })
  .on('exit', function () {
    socket.end()
  })
}).listen(8080)

repl_client simply creates a new socket connection to port 8080 through net.connect, and pipes any data coming from stdin (your terminal) through that socket. Similarly, any data arriving from the socket is piped to stdout (your terminal). It should be clear that we have created a way to take input and send it via a socket to port 8080, listening for any data that the socket may send back to us.

repl_server closes the loop. We first create a new TCP (Transmission Control Protocol) server with net.createServer, binding to port 8080 via .listen. The callback passed to net.createServer will receive a reference to the bound socket. Within the enclosure of that callback we instantiate a new REPL instance, giving it a nice prompt (> here, but could be any string), indicating that it should both listen for input from, and broadcast output to, the passed socket reference, indicating that the socket data should be treated as terminal data (which has special encoding).

We can now type something like console.log("hello") into the client terminal, and see hello displayed.

To confirm that the execution of our JavaScript commands is occurring in the server instance, type console.log(process.argv) into the client, and the server will display an object containing the current process path, which will be repl_server.js.

It should be clear from this demonstration that we have created a way to remotely control Node processes. It is a short step from here to multi-node analytics tools, remote memory management, automatic server administration, and so forth.

Summary

In this chapter we've outlined the key problems Node's designers sought to solve, and how their solution has made the creation of easily scalable, high-concurrency networked systems easier for an open community of developers. We've seen how JavaScript has been given very useful new powers, how its evented model has been extended, and how V8 can be configured to further customize the JavaScript runtime.

Through examples, we've learned how I/O is handled by Node, how to program the REPL, as well as how to manage inputs and outputs to the process object. The goal of demonstrating how Node allows applications to be intelligently constructed out of well-formed pieces in a principled way has begun. In the next chapter, we will delve deeper into asynchronous programming, learn how to manage more complex event chains, and develop more powerful programs using Node's model.

Left arrow icon Right arrow icon
Download code icon Download Code

Key benefits

  • Master the latest techniques for building real-time, big data applications, integrating Facebook, Twitter, and other network services
  • Tame asynchronous programming, the event loop, and parallel data processing
  • Use the Express and Path frameworks to speed up development and deliver scalable, higher quality software more quickly

Description

Node.js is a modern development stack focused on providing an easy way to build scalable network software. Backed by a growing number of large companies and a rapidly increasing developer base, Node is revolutionizing the way that software is being built today. Powered by Google's V8 engine and built out of C++ modules, this is a JavaScript environment for the enterprise.Mastering Node.js will take the reader deep into this exciting development environment. Beginning with a comprehensive breakdown of its innovative non-blocking evented design, Node's structure is explained in detail, laying out how its blazingly fast I/O performance simplifies the creation of fast servers, scalable architectures, and responsive web applications.Mastering Node.js takes you through a concise yet thorough tour of Node's innovative evented non-blocking design, showing you how to build professional applications with the help of detailed examples.Learn how to integrate your applications with Facebook and Twitter, Amazon and Google, creating social apps and programs reaching thousands of collaborators on the cloud. See how the Express and Path frameworks make the creation of professional web applications painless. Set up one, two, or an entire server cluster with just a few lines of code, ready to scale as soon as you're ready to launch. Move data seamlessly between databases and file systems, between clients, and across network protocols, using a beautifully designed, consistent, and predictable set of tools.Mastering Node.js contains all of the examples and explanations you'll need to build applications in a short amount of time and at a low cost, running on a scale and speed that would have been nearly impossible just a few years ago.

Who is this book for?

If you've ever built a web page and would like to build network software using the language and style you already know, Node will make that process simple, and even fun. If you understand what a server is, what a client is, and how to write JavaScript, you are already halfway to mastering Node.js!

What you will learn

  • Discover how Node uses Google s V8 engine to create high-speed JavaScript on the server
  • Use events to create non-blocking systems with high throughput
  • Create secure servers across all major network protocols
  • Manage thousands of concurrent clients without slowing down
  • Handle data, files, and protocol streams with ease
  • Leverage Node s module system to design sane applications that are easy to extend
  • Optimize and debug server-side JavaScript for increased performance
  • Learn scaling techniques and parallelize operations across multiple cores
Estimated delivery fee Deliver to Czechia

Premium delivery 7 - 10 business days

€25.95
(Includes tracking information)

Product Details

Country selected
Publication date, Length, Edition, Language, ISBN-13
Publication date : Nov 25, 2013
Length: 346 pages
Edition : 1st
Language : English
ISBN-13 : 9781782166320
Vendor :
Node.js Developers
Languages :
Tools :

What do you get with Print?

Product feature icon Instant access to your digital copy whilst your Print order is Shipped
Product feature icon Paperback book shipped to your preferred address
Product feature icon Redeem a companion digital copy on all Print orders
Product feature icon Access this title in our online reader with advanced features
Product feature icon DRM FREE - Read whenever, wherever and however you want
OR
Modal Close icon
Payment Processing...
tick Completed

Shipping Address

Billing Address

Shipping Methods
Estimated delivery fee Deliver to Czechia

Premium delivery 7 - 10 business days

€25.95
(Includes tracking information)

Product Details

Publication date : Nov 25, 2013
Length: 346 pages
Edition : 1st
Language : English
ISBN-13 : 9781782166320
Vendor :
Node.js Developers
Languages :
Tools :

Packt Subscriptions

See our plans and pricing
Modal Close icon
€18.99 billed monthly
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Simple pricing, no contract
€189.99 billed annually
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Choose a DRM-free eBook or Video every month to keep
Feature tick icon PLUS own as many other DRM-free eBooks or Videos as you like for just €5 each
Feature tick icon Exclusive print discounts
€264.99 billed in 18 months
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Choose a DRM-free eBook or Video every month to keep
Feature tick icon PLUS own as many other DRM-free eBooks or Videos as you like for just €5 each
Feature tick icon Exclusive print discounts

Frequently bought together


Stars icon
Total 129.97
Mastering Node.js
€41.99
Node.js Blueprints
€45.99
Node Cookbook: Second Edition
€41.99
Total 129.97 Stars icon

Table of Contents

13 Chapters
1. Understanding the Node Environment Chevron down icon Chevron up icon
2. Understanding Asynchronous Event-Driven Programming Chevron down icon Chevron up icon
3. Streaming Data Across Nodes and Clients Chevron down icon Chevron up icon
4. Using Node to Access the Filesystem Chevron down icon Chevron up icon
5. Managing Many Simultaneous Client Connections Chevron down icon Chevron up icon
6. Creating Real-time Applications Chevron down icon Chevron up icon
7. Utilizing Multiple Processes Chevron down icon Chevron up icon
8. Scaling Your Application Chevron down icon Chevron up icon
9. Testing your Application Chevron down icon Chevron up icon
A. Organizing Your Work Chevron down icon Chevron up icon
B. Introducing the Path Framework Chevron down icon Chevron up icon
C. Creating your own C++ Add-ons Chevron down icon Chevron up icon
Index Chevron down icon Chevron up icon

Customer reviews

Top Reviews
Rating distribution
Full star icon Full star icon Full star icon Full star icon Half star icon 4.4
(10 Ratings)
5 star 80%
4 star 0%
3 star 10%
2 star 0%
1 star 10%
Filter icon Filter
Top Reviews

Filter reviews by




Amazon Customer Apr 14, 2014
Full star icon Full star icon Full star icon Full star icon Full star icon 5
Like the title of the book suggests, if you're looking to dive deeper into node.js, this publication is an ideal companion – tackling more important and practical higher-level concepts.
Amazon Verified review Amazon
Jay Brizle Aug 21, 2015
Full star icon Full star icon Full star icon Full star icon Full star icon 5
It is well written and explains things well. I will say that this is the book that you want if you are trying to learn core Node and aren't looking to use all of the extra packages/modules that other books and things seem to introduce very early to get you up and running building something "cool" from the start. That is my real reason for even writing a review, just to let others know. It starts off seeming like you have exposure to Node already I would say though. After spending a lot of time over the last month with Node and reading, watching and attempting some things I was able to understand what was being said from the beginning of the book that I recognized I would be clueless what he was talking about had I not. Maybe that's just me though. But he does rewind and spends chapters going over the base things of Node well. My opinion is this is one of the books to open when you have made your way around Node at least a bit and are ready or curious to understand some things further. Or as a mixin with the other things your attempting to learn Node with. It then goes into real world in production concerns, which is cool. He even touches on things like how you can configure the underlying V8 engine for your Node installment from the command-line. This does not start with a "Hello, Node" example or introduce a bunch of Node packages that you also need to go run off and learn the api to. It is, mostly, about working with core Node and gaining understanding there. If you are wanting to understand Node internals a bit and wanting to build from there this is a good book.
Amazon Verified review Amazon
ELIAS POLITAKIS Oct 22, 2015
Full star icon Full star icon Full star icon Full star icon Full star icon 5
An excellent book on the internals of Node.js that covers almost EVERY aspect for producing scalable Network Servers, but sadly not in the depth I was expecting. Still, the book covers libuv Event Loop, node.js processes and forks, CPU clustering with HTTP Server example, Socket I/O and Streams, Session Management tools such as Redis, Reverse Proxies and RabbitMQ, Errors and Exceptions, Amazon Web Services and a little of Native C++ Addons. The book's figures are not brilliant as the author fails big-time to produce understandable drawings (I had to scratch my head a lot until I could understand them) and it does not get into technologies such as MemCached or Redis too much. Still, you can get up-to-speed with Node.js in just 48 hours and seek other material from there. HIGHLY RECOMMENDED for newbies into node.js advanced programming.
Amazon Verified review Amazon
Michael Benin Jan 22, 2015
Full star icon Full star icon Full star icon Full star icon Full star icon 5
I recommend this book for anyone who wants to learn NodeJS. The examples are relevant and up to date. I really enjoyed reading about scaling techniques and learning how Node uses V8. The only thing missing is a reference to bluebird for a Promise library, other than that, everything the book promises in "What you will learn from this book" on the back is true :)
Amazon Verified review Amazon
Jools Feb 11, 2014
Full star icon Full star icon Full star icon Full star icon Full star icon 5
This book is indeed about 'mastering' node. It is a book for the professional with a need to understand where the true strengths of the framework lie. Above all it dispenses with the notion that node can't 'do' multi-CPU machines and elegantly explains why the node solution will trump the old multi-threaded blocking options.I was relieved to find there is no 'introduction' to the javascript language (for example). The book assumes you are familiar with node already. Indeed you are really straight 'in there' with e.g. Streams2, scaling servers and child process forking; which is just what I wanted as there is a paucity of documentation and discussion about node.js out there, even on Stackoverflow. This book contains quite a lot more information and guidance than I could find on the internet, so for me it is a good buy. As usual with all tech books, the program examples don't render well on Kindle, so this time I bought the hardcopy !
Amazon Verified review Amazon
Get free access to Packt library with over 7500+ books and video courses for 7 days!
Start Free Trial

FAQs

What is the digital copy I get with my Print order? Chevron down icon Chevron up icon

When you buy any Print edition of our Books, you can redeem (for free) the eBook edition of the Print Book you’ve purchased. This gives you instant access to your book when you make an order via PDF, EPUB or our online Reader experience.

What is the delivery time and cost of print book? Chevron down icon Chevron up icon

Shipping Details

USA:

'

Economy: Delivery to most addresses in the US within 10-15 business days

Premium: Trackable Delivery to most addresses in the US within 3-8 business days

UK:

Economy: Delivery to most addresses in the U.K. within 7-9 business days.
Shipments are not trackable

Premium: Trackable delivery to most addresses in the U.K. within 3-4 business days!
Add one extra business day for deliveries to Northern Ireland and Scottish Highlands and islands

EU:

Premium: Trackable delivery to most EU destinations within 4-9 business days.

Australia:

Economy: Can deliver to P. O. Boxes and private residences.
Trackable service with delivery to addresses in Australia only.
Delivery time ranges from 7-9 business days for VIC and 8-10 business days for Interstate metro
Delivery time is up to 15 business days for remote areas of WA, NT & QLD.

Premium: Delivery to addresses in Australia only
Trackable delivery to most P. O. Boxes and private residences in Australia within 4-5 days based on the distance to a destination following dispatch.

India:

Premium: Delivery to most Indian addresses within 5-6 business days

Rest of the World:

Premium: Countries in the American continent: Trackable delivery to most countries within 4-7 business days

Asia:

Premium: Delivery to most Asian addresses within 5-9 business days

Disclaimer:
All orders received before 5 PM U.K time would start printing from the next business day. So the estimated delivery times start from the next day as well. Orders received after 5 PM U.K time (in our internal systems) on a business day or anytime on the weekend will begin printing the second to next business day. For example, an order placed at 11 AM today will begin printing tomorrow, whereas an order placed at 9 PM tonight will begin printing the day after tomorrow.


Unfortunately, due to several restrictions, we are unable to ship to the following countries:

  1. Afghanistan
  2. American Samoa
  3. Belarus
  4. Brunei Darussalam
  5. Central African Republic
  6. The Democratic Republic of Congo
  7. Eritrea
  8. Guinea-bissau
  9. Iran
  10. Lebanon
  11. Libiya Arab Jamahriya
  12. Somalia
  13. Sudan
  14. Russian Federation
  15. Syrian Arab Republic
  16. Ukraine
  17. Venezuela
What is custom duty/charge? Chevron down icon Chevron up icon

Customs duty are charges levied on goods when they cross international borders. It is a tax that is imposed on imported goods. These duties are charged by special authorities and bodies created by local governments and are meant to protect local industries, economies, and businesses.

Do I have to pay customs charges for the print book order? Chevron down icon Chevron up icon

The orders shipped to the countries that are listed under EU27 will not bear custom charges. They are paid by Packt as part of the order.

List of EU27 countries: www.gov.uk/eu-eea:

A custom duty or localized taxes may be applicable on the shipment and would be charged by the recipient country outside of the EU27 which should be paid by the customer and these duties are not included in the shipping charges been charged on the order.

How do I know my custom duty charges? Chevron down icon Chevron up icon

The amount of duty payable varies greatly depending on the imported goods, the country of origin and several other factors like the total invoice amount or dimensions like weight, and other such criteria applicable in your country.

For example:

  • If you live in Mexico, and the declared value of your ordered items is over $ 50, for you to receive a package, you will have to pay additional import tax of 19% which will be $ 9.50 to the courier service.
  • Whereas if you live in Turkey, and the declared value of your ordered items is over € 22, for you to receive a package, you will have to pay additional import tax of 18% which will be € 3.96 to the courier service.
How can I cancel my order? Chevron down icon Chevron up icon

Cancellation Policy for Published Printed Books:

You can cancel any order within 1 hour of placing the order. Simply contact customercare@packt.com with your order details or payment transaction id. If your order has already started the shipment process, we will do our best to stop it. However, if it is already on the way to you then when you receive it, you can contact us at customercare@packt.com using the returns and refund process.

Please understand that Packt Publishing cannot provide refunds or cancel any order except for the cases described in our Return Policy (i.e. Packt Publishing agrees to replace your printed book because it arrives damaged or material defect in book), Packt Publishing will not accept returns.

What is your returns and refunds policy? Chevron down icon Chevron up icon

Return Policy:

We want you to be happy with your purchase from Packtpub.com. We will not hassle you with returning print books to us. If the print book you receive from us is incorrect, damaged, doesn't work or is unacceptably late, please contact Customer Relations Team on customercare@packt.com with the order number and issue details as explained below:

  1. If you ordered (eBook, Video or Print Book) incorrectly or accidentally, please contact Customer Relations Team on customercare@packt.com within one hour of placing the order and we will replace/refund you the item cost.
  2. Sadly, if your eBook or Video file is faulty or a fault occurs during the eBook or Video being made available to you, i.e. during download then you should contact Customer Relations Team within 14 days of purchase on customercare@packt.com who will be able to resolve this issue for you.
  3. You will have a choice of replacement or refund of the problem items.(damaged, defective or incorrect)
  4. Once Customer Care Team confirms that you will be refunded, you should receive the refund within 10 to 12 working days.
  5. If you are only requesting a refund of one book from a multiple order, then we will refund you the appropriate single item.
  6. Where the items were shipped under a free shipping offer, there will be no shipping costs to refund.

On the off chance your printed book arrives damaged, with book material defect, contact our Customer Relation Team on customercare@packt.com within 14 days of receipt of the book with appropriate evidence of damage and we will work with you to secure a replacement copy, if necessary. Please note that each printed book you order from us is individually made by Packt's professional book-printing partner which is on a print-on-demand basis.

What tax is charged? Chevron down icon Chevron up icon

Currently, no tax is charged on the purchase of any print book (subject to change based on the laws and regulations). A localized VAT fee is charged only to our European and UK customers on eBooks, Video and subscriptions that they buy. GST is charged to Indian customers for eBooks and video purchases.

What payment methods can I use? Chevron down icon Chevron up icon

You can pay with the following card types:

  1. Visa Debit
  2. Visa Credit
  3. MasterCard
  4. PayPal
What is the delivery time and cost of print books? Chevron down icon Chevron up icon

Shipping Details

USA:

'

Economy: Delivery to most addresses in the US within 10-15 business days

Premium: Trackable Delivery to most addresses in the US within 3-8 business days

UK:

Economy: Delivery to most addresses in the U.K. within 7-9 business days.
Shipments are not trackable

Premium: Trackable delivery to most addresses in the U.K. within 3-4 business days!
Add one extra business day for deliveries to Northern Ireland and Scottish Highlands and islands

EU:

Premium: Trackable delivery to most EU destinations within 4-9 business days.

Australia:

Economy: Can deliver to P. O. Boxes and private residences.
Trackable service with delivery to addresses in Australia only.
Delivery time ranges from 7-9 business days for VIC and 8-10 business days for Interstate metro
Delivery time is up to 15 business days for remote areas of WA, NT & QLD.

Premium: Delivery to addresses in Australia only
Trackable delivery to most P. O. Boxes and private residences in Australia within 4-5 days based on the distance to a destination following dispatch.

India:

Premium: Delivery to most Indian addresses within 5-6 business days

Rest of the World:

Premium: Countries in the American continent: Trackable delivery to most countries within 4-7 business days

Asia:

Premium: Delivery to most Asian addresses within 5-9 business days

Disclaimer:
All orders received before 5 PM U.K time would start printing from the next business day. So the estimated delivery times start from the next day as well. Orders received after 5 PM U.K time (in our internal systems) on a business day or anytime on the weekend will begin printing the second to next business day. For example, an order placed at 11 AM today will begin printing tomorrow, whereas an order placed at 9 PM tonight will begin printing the day after tomorrow.


Unfortunately, due to several restrictions, we are unable to ship to the following countries:

  1. Afghanistan
  2. American Samoa
  3. Belarus
  4. Brunei Darussalam
  5. Central African Republic
  6. The Democratic Republic of Congo
  7. Eritrea
  8. Guinea-bissau
  9. Iran
  10. Lebanon
  11. Libiya Arab Jamahriya
  12. Somalia
  13. Sudan
  14. Russian Federation
  15. Syrian Arab Republic
  16. Ukraine
  17. Venezuela