Enabling a Node.js Server-Side App on Windows Azure
Use JavaScript to power your server-side logic in an Azure cloud app
April 11, 2012
Node.js represents the return of server-side JavaScript, plain and simple. Are you screaming "foul!" yet? It turns out that JavaScript has evolved tremendously over the years since its introduction, in both robustness and performance. A JavaScript-based Node.js infrastructure offers quite a few benefits to the server application developer: It's very lightweight in terms of memory and CPU overhead, can handle large numbers of concurrent requests because of its asynchronous-by-default design, supports remote interactive debugging, and is written in a language already familiar to most web developers. On top of all that, Node.js is now an officially supported option for implementing Azure Web and Worker roles. In this article, we'll explore the basic architecture of a Node.js solution that will prepare you to craft your next great server application... with JavaScript!
Node.js Architecture
Node.js is an open-source platform that relies on Google Chrome's V8 JavaScript runtime and a number of modules that are either built into Node.js or available from the community. The basic node application runs an instance of node.exe, passing it the name of a JavaScript file that contains the entry point for the application. The script is executed on a single thread within that process. In the case of a web server application, that script file -- shown in the example in Figure 1 -- defines a callback that responds to HTTP requests much as a controller action does in an ASP.NET MVC application, as shown in Figure 2.
public class ParadeController : Controller{ // // GET: / public JsonResult Index() { var parades = new[] { new { name = "Rose Parade 2012", date="1/2/2012", city= "Pasadena", state = "CA", route= "From Orange Grove, down Colorado to Sierra Madre.", image="Megazord.png" }, new { name = "Thanksgiving Day 2011", date="11/24/2011", city= "New York City", state = "NY", route= "From 77th St, down Central Park West, then...", image="Bug.png"} }; return Json(parades, JsonRequestBehavior.AllowGet); }}
When hosted within Windows Azure, a Node.js web server application can take the form of either a Web role or a Worker role, as shown in Figure 3.
Figure 3: Architecture of Node.js on Azure
In the case of a Web role, all requests are received by Microsoft IIS 7 and passed to a native IIS module called iisnode. This module is responsible for starting up process instances of node.exe with the configured script (named Server.js by convention) in response to web requests. iisnode handles creating new instances of node.exe so as to leverage the concurrency available to multiple-core servers, directs requests to idle process instances, manages a request queue for handling requests that occur when all instances are busy, and handles returning server busy responses when the maximum numbers of processes and queued requests have been reached. The iisnode module relies on the IIS URL Rewrite module and can be configured to run side by side with other modules in IIS, enabling you to route requests to ASP.NET and static files in addition to your Node.js application.
When a Web role instance starts, it runs a start-up task command script that copies node.exe to C:Program Files(x86)odejs and runs a Microsoft Windows Installer (MSI) file that installs iisnode. Both of these binaries are included in the Web role package's bin folder that is created when you add a Web role to your hosted service. The port at which the node.js web server application is reached is defined by the input endpoint declared within the service definition (ServiceDefinition.csdef).
Worker roles are much more like the basic node application in that they directly run node.exe for Server.js when the role instance starts. In this case, a program entry point is defined within the service definition, which runs the following command line:
node.exe .server.js
The port on which the Node.js web server application is reached is defined by setting the PORT environment variable to the value of the TCP input endpoint (also configured in the service definition).
Getting Started with the SDK
Although you could build these command scripts and service definition files yourself, package them, and then upload the package to Windows Azure, there is already an SDK for doing that: the Windows Azure SDK for Node.js. This SDK installs the Node.js executable, a core install of IIS Node, Node Package Manager (NPM) for Windows (which helps you download and install modules from the community), and Windows PowerShell scripts that you use for creating the solution on the file system (e.g., creating the service and adding roles) and publishing it to Windows Azure. When developing an application using this SDK, you can do all your work from the command line and never get into Visual Studio.
Let's look at the typical development life cycle using the PowerShell scripts included with the Node.js SDK. All PowerShell cmdlets discussed here are accessed within an instance of Windows Azure PowerShell for Node.js, whose shortcut is available on the Start menu, under the Windows Azure SDK for Node.js folder.
Set Up Your Environment
The first time you use the SDK, you will need to set up your environment so that it has access to your Azure subscriptions. You do this by running the Get-AzurePublishSettings cmdlet. Running this cmdlet creates a new certificate, adds it as management certificate to all subscriptions for which you're a co-admin, as shown in Figure 4, and then downloads a profile file containing the certificate and all subscriptions to which it has access.
Figure 4: Example of a management certificate created by Get-AzurePublishSettings
Once you have this profile file, run the Import-AzurePublishSettings cmdlet, passing it the path to the profile file. The management certificate is imported into the Personal store of the current user, and the list of subscriptions associated with this certificate is cached under your user's roaming application data folder (e.g., C:UsersusernameAppDataRoamingWindows Azure SDK Deployment Cmdlets). The first subscription listed in this file is used by default for all cmdlets requiring a subscription name, if you didn't provide a subscription name at the command line.
Create and Run Your Service
Now you are ready to do the equivalent of creating a cloud project in Visual Studio. You do this by executing the New-AzureService cmdlet, providing it a name for the hosted service. Then you can call the Add-AzureNodeWebRole or Add-AzureNodeWorkerRole cmdlet, providing a name for the role you want to add. What these three cmdlets do is copy and modify the scaffolding files found in C:Program Files (x86)Microsoft SDKsWindows AzureNodejsNov2011PowerShellScaffolding to create the project structure using the service and role names you specify in the current directory.
Regardless of whether you chose to build a Web role or Worker role, you will have a Server.js file in the role's directory. Edit Server.js in the text editor of your choice. For Web roles, you should edit the web.config file by adding the iisnode element within the system.webServerElement to disable logging, as shown in Figure 5. Doing so avoids a fault that crashes the emulator when it is run multiple times.
To run your hosted service in the Azure emulator, execute the Start-AzureEmulator cmdlet. If you specify the ‑Launch parameter, when the emulator is ready it will automatically open a browser window pointed to the address of your application.
Publish Your Service to Windows Azure
Once you are satisfied your application works as desired, execute the Publish-AzureService cmdlet, providing values for the subscription, name of the hosted service, name of the storage account to upload the package to, the geographic location where you want your service to run, and which slot you want to run it in. Figure 6 shows an example of the Publish-AzureService cmdlet with these values specified. If you need to make changes to the deployed service, simply make the changes and run Publish-AzureService again-it will automatically perform an upgrade.
Publish-AzureService -Subscription "TejadaNET" -Name "tejadanet-floatfanservice" -StorageAccountName "tejadanet" -Location "South Central US" -Slot "Production"
Interactive Debugging with Node.js
Interactive debugging of Node.js applications is powerful, impressive, and simple. Basically, you start your node process, run another application called node-inspector, and then navigate to the URL displayed by this application using a WebKit-based browser (such as Safari or Chrome). Once there, you can set breakpoints, step execution, examine call stacks, and view variable values-even for your script running on a remote machine!
Interactive debugging of a Node.js app works equally well on Azure. The debugging example in Figure 7 shows the debugger hitting a breakpoint in a script running on an Azure Web role, all from Safari running on my local machine.
Figure 7: Interactive debugging of an Azure-hosted Node.js application
Getting interactive debugging working on your machine takes only a little bit of setup. The MSI of iisnode that ships with the SDK provides only a core installation of iisnode, which unfortunately does not include the required iisnode-inspector.dll. To resolve this, download and install the latest version of the "full" iisnode edition. Then copy the MSI over the one found under your Web role's bin directory (you will have to rename the MSI to iisnode.msi, as shown in Figure 8).
Figure 8: The bin directory of a Web role
Open web.cloud.config and change the value of the debuggingEnabled attribute of the iisnode element to "true" (Figure 9).
Then publish your service. To access the debugger, open Safari or Chrome and point to the URL of your hosted service, appended with "/Server.js/debug"-for example:
http://.cloudapp.net/Server.js/debug
In the web page that appears (Figure 7), click the Scripts tab, choose Server.js from the drop-down list at the top, and start debugging!
Community-Driven
By this point, you should have an understanding of how Node.js runs in the context of Windows Azure, but we've only scratched the surface of what Node.js is capable of. A lot of the value of Node.js comes from the community and the packages you acquire using NPM for Windows (included with the SDK). To get most packages, you simply run the following command from PowerShell:
npm install
Running this command will download the package and its dependencies into a node_modules subfolder of the current directory. You will find packages for diverse needs, from packages for creating ASP.NET MVC web server applications (called Express) to packages for working against Windows Azure blobs, tables, and queues (fittingly called Azure). You can also search the NPM Registry of available packages. Check out the Learning Path for additional resources. Happy noding!
About the Author
You May Also Like