Shaun Xu

The Sheep-Pen of the Shaun


News

logo

Shaun, the author of this blog is a semi-geek, clumsy developer, passionate speaker and incapable architect with about 10 years experience in .NET. He hopes to prove that software development is art rather than manufacturing. He's into cloud computing platform and technologies (Windows Azure, Aliyun) as well as WCF and ASP.NET MVC. Recently he's falling in love with JavaScript and Node.js.

Currently Shaun is working at IGT Technology Development (Beijing) Co., Ltd. as the architect responsible for product framework design and development.

MVP

My Stats

  • Posts - 94
  • Comments - 337
  • Trackbacks - 0

Tag Cloud


Recent Comments


Recent Posts


Archives


Post Categories



In the first post of this series I introduced on how to run Node.js application on Windows. In the second one I demonstrated about how to use SQL Server in Node.js. That was the steps when I was learning Node.js, firstly made it work on Windows, then try to use SQL Server. But returned back to my original goal, I need to implement a synchronization service for Wang Tao’s worktile, and planed to have a prototype hosted on Windows Azure. So the previous two posts are preparation. In this post I am going to describe how to host a Node.js website on Windows Azure Web Site.

 

Node.js on Windows Azure Web Site via Git Deployment

Windows Azure Web Site (a.k.a. WAWS) is a new service which introduced in Microsoft Meet Windows Azure event on June. It provides a low-cost, build-in templates and simple way to host websites on the cloud. For more information about WAWS, please refer to my previous posts here, here and here.

WAWS is the simplest way for us to deploy our Node.js website I think.

-  IIS and IISNode are installed and configured in WAWS environment, so that we don’t need to install and anything when deployment.

- WAWS supports multiple deployment approaches such as TFS, FTP and Git. For Node.js, FTP and Git deployment are very easy and quick.

- WAWS provides three types of scale mode, which are free, shared and reserved. The cost is lower than Windows Azure Cloud Service (a.k.a. WACS) if we only need a website with a database.

- WAWS supports Windows Azure SQL Database (a.k.a. WASD) as well as MySQL.

 

Let’s have a look on how simple and easy to have a website on WAWS in Node.js. First of all, we need to create a new WAWS. Since I will demonstrate how to use WASD from Node.js later this post we will create a WASD here as well. Go to windows azure developer portal, from the NEW button select COMPUTER, WEB SITE, CREATE WITH DATABASE.

image

Once the website was created we go to its dashboard, click the Set up Git publishing link on the right side.

image

After few seconds Windows Azure will finish the Git deployment configuration. If this is the first time you configured Git or FTP deployment on Windows Azure, you need to click the Reset deployment credentials link on the dashboard to provide the deployment user name and password.

image

Next, let’s clone the Git repository from Windows Azure to our local disk. If you don’t have Git installed on your machine you can download it here. After installed we will open the Git Bash from the start menu Git folder. In the command windows navigate to the folder we want to clone. For example in my case I ‘m going to use the folder “D:\Research\nodejs\apps\nodejssample” so I need to go to ““D:\Research\nodejs\apps” and make sure the folder “nodejssample” does NOT exists, since Git will create this folder when it clones.

Back to the developer portal deployment page, copy the Git URL and then execute the Git clone command as shown below. When it needs password, specify the password we set in the previous step.

image

Now the repository had been cloned from WAWS to our local disk. Then we will use another GUI tool to commit and push our changes named GitHub for Windows.

GitHub for Windows is a GUI tool running on Windows for easily control the repositories on GitHub. We can use this tool to control our repository cloned from WAWS as well. You can download it here.

Open the GitHub for Windows, open the folder where the repository we had just cloned in file explorer, and then drag this folder into the GitHub for Windows.

image

When we clicked this repository on the GitHub windows we need to input the credentials, which is what we specified in developer portal. Currently there no changes in local folder.

Since the WAWS hosts Node.js application through IIS and IISNode, it will start the JavaScript file named “server.js”. So we must create a source file named “server.js” and this is the entry of our website. Create a web server and let it listen on port which come from “process.env.PORT”.

“process.env.PORT” means it will retrieve the port number from the environment variant named “PORT”. Since the WAWS hosts all website behind the windows azure router and firewall, this environment variant represents the correct internal port our WAWS is listening on.

   1: var http = require("http");
   2:  
   3: http.createServer(function (req, res) {
   4:     res.writeHead(200, {"Content-Type": "text/plain"});
   5:     res.end("Hello Node.js and Windows Azure Website!\n");
   6: }).listen(process.env.port);
   7:  
   8: console.log("Server started.");

Once we saved the file and back to GitHub window we would found it detected this change. Then we can commit it.

image

Then click the “publish” button on top of the window. It will publish our changes to the WAWS remote repository, and then WAWS will begin to deploy.

image

Now back to windows azure developer portal, there will be a new deployment in the deployment page under this website and have a try.

image

NPM Modules in Windows Azure Web Site

Use NPM modules and deploy modules alone with our Node.js website is pretty simple, too. All modules we added are located at the “node_modules” subfolder so we do not need any extra effort.

For example, I installed the “express” module in my website through the NPM command. It downloaded all necessary files to “node_modules” subfolder. And then I will change my code to use “express”.

   1: var express = require("express");
   2: var app = express();
   3:  
   4: app.get("/", function(req, res) {
   5:     res.send("Hello Node.js, Express and Windows Azure Web Site.");
   6: });
   7:  
   8: app.get("/Echo/:value", function(req, res) {
   9:     var value = req.params.value;
  10:     res.json({
  11:         "Value" : value,
  12:         "Time" : new Date()
  13:     });
  14: });
  15:  
  16: console.log("Web application opened.");
  17: app.listen(process.env.PORT);

Then go to GitHub, commit and sync to remote repository.

image

Then in windows azure we will found the new deployment.

image

And if we refresh the website home page we will find the new content. Also we can test the new function we added in this changes.

image

 

Work with Windows Azure SQL Database

Let’s continue use the SQL schema and data I mentioned in my previous post, execute the script below under the SQL Database I created at the beginning.

   1: /****** Object:  Table [dbo].[Resource]    Script Date: 9/4/2012 3:47:14 PM ******/
   2: SET ANSI_NULLS ON
   3: GO
   4: SET QUOTED_IDENTIFIER ON
   5: GO
   6: CREATE TABLE [dbo].[Resource](
   7:     [Key] [varchar](256) NOT NULL,
   8:     [Culture] [varchar](8) NOT NULL,
   9:     [Value] [nvarchar](4000) NOT NULL,
  10:  CONSTRAINT [PK_Resource] PRIMARY KEY CLUSTERED 
  11: (
  12:     [Key] ASC,
  13:     [Culture] ASC
  14: )WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF)
  15: )
  16:  
  17: GO
  18: INSERT [dbo].[Resource] ([Key], [Culture], [Value]) VALUES (N'Controller_HomeAbout_Message', N'en-US', N'Your app description page.')
  19: GO
  20: INSERT [dbo].[Resource] ([Key], [Culture], [Value]) VALUES (N'Controller_HomeAbout_Message', N'zh-CN', N'???????')
  21: GO
  22: INSERT [dbo].[Resource] ([Key], [Culture], [Value]) VALUES (N'Controller_HomeContact_Message', N'en-US', N'Your contact page.')
  23: GO
  24: INSERT [dbo].[Resource] ([Key], [Culture], [Value]) VALUES (N'Controller_HomeContact_Message', N'zh-CN', N'?????????')
  25: GO
  26: INSERT [dbo].[Resource] ([Key], [Culture], [Value]) VALUES (N'Controller_HomeIndex_Message', N'en-US', N'Modify this template to jump-start your ASP.NET MVC application.')
  27: GO
  28: INSERT [dbo].[Resource] ([Key], [Culture], [Value]) VALUES (N'Controller_HomeIndex_Message', N'zh-CN', N'??????,??????ASP.NET MVC?????')
  29: GO
  30: INSERT [dbo].[Resource] ([Key], [Culture], [Value]) VALUES (N'Model_AccountModels_LoginModel_Password_Display', N'en-US', N'Password')
  31: GO
  32: INSERT [dbo].[Resource] ([Key], [Culture], [Value]) VALUES (N'Model_AccountModels_LoginModel_Password_Display', N'zh-CN', N'??')
  33: GO
  34: INSERT [dbo].[Resource] ([Key], [Culture], [Value]) VALUES (N'Model_AccountModels_LoginModel_Password_Required', N'en-US', N'Please input {0}.')
  35: GO
  36: INSERT [dbo].[Resource] ([Key], [Culture], [Value]) VALUES (N'Model_AccountModels_LoginModel_Password_Required', N'zh-CN', N'???{0}?')
  37: GO
  38: INSERT [dbo].[Resource] ([Key], [Culture], [Value]) VALUES (N'Model_AccountModels_LoginModel_RememberMe_Display', N'en-US', N'Remember me?')
  39: GO
  40: INSERT [dbo].[Resource] ([Key], [Culture], [Value]) VALUES (N'Model_AccountModels_LoginModel_RememberMe_Display', N'zh-CN', N'???????')
  41: GO
  42: INSERT [dbo].[Resource] ([Key], [Culture], [Value]) VALUES (N'Model_AccountModels_LoginModel_UserName_Display', N'en-US', N'User Name')
  43: GO
  44: INSERT [dbo].[Resource] ([Key], [Culture], [Value]) VALUES (N'Model_AccountModels_LoginModel_UserName_Display', N'zh-CN', N'???')
  45: GO
  46: INSERT [dbo].[Resource] ([Key], [Culture], [Value]) VALUES (N'Model_AccountModels_LoginModel_UserName_Required', N'en-US', N'Please input the {0}.')
  47: GO
  48: INSERT [dbo].[Resource] ([Key], [Culture], [Value]) VALUES (N'Model_AccountModels_LoginModel_UserName_Required', N'zh-CN', N'???{0}?')
  49: GO
  50: INSERT [dbo].[Resource] ([Key], [Culture], [Value]) VALUES (N'Model_AccountModels_RegisterModel_ConfirmPassword_Compare', N'en-US', N'The password and confirmation password do not match.')
  51: GO
  52: INSERT [dbo].[Resource] ([Key], [Culture], [Value]) VALUES (N'Model_AccountModels_RegisterModel_ConfirmPassword_Compare', N'zh-CN', N'???????????')
  53: GO
  54: INSERT [dbo].[Resource] ([Key], [Culture], [Value]) VALUES (N'Model_AccountModels_RegisterModel_ConfirmPassword_Display', N'en-US', N'Confirm password')
  55: GO
  56: INSERT [dbo].[Resource] ([Key], [Culture], [Value]) VALUES (N'Model_AccountModels_RegisterModel_ConfirmPassword_Display', N'zh-CN', N'??????')
  57: GO
  58: INSERT [dbo].[Resource] ([Key], [Culture], [Value]) VALUES (N'Model_AccountModels_RegisterModel_Password_StringLength', N'en-US', N'The {0} must be at least {2} characters long.')
  59: GO
  60: INSERT [dbo].[Resource] ([Key], [Culture], [Value]) VALUES (N'Model_AccountModels_RegisterModel_Password_StringLength', N'zh-CN', N'{0}?????')
  61: GO
  62: INSERT [dbo].[Resource] ([Key], [Culture], [Value]) VALUES (N'View_AccountLogin_ExtenalAccount', N'en-US', N'Use another service to log in.')
  63: GO
  64: INSERT [dbo].[Resource] ([Key], [Culture], [Value]) VALUES (N'View_AccountLogin_ExtenalAccount', N'zh-CN', N'?????????')
  65: GO
  66: INSERT [dbo].[Resource] ([Key], [Culture], [Value]) VALUES (N'View_AccountLogin_LocalAccount', N'en-US', N'Use a local account to log in.')
  67: GO
  68: INSERT [dbo].[Resource] ([Key], [Culture], [Value]) VALUES (N'View_AccountLogin_LocalAccount', N'zh-CN', N'?????????')
  69: GO
  70: INSERT [dbo].[Resource] ([Key], [Culture], [Value]) VALUES (N'View_AccountLogin_RegisterIfNoAccount', N'en-US', N'{0} if you don''t have an account.')
  71: GO
  72: INSERT [dbo].[Resource] ([Key], [Culture], [Value]) VALUES (N'View_AccountLogin_RegisterIfNoAccount', N'zh-CN', N'??????,?{0}?')
  73: GO
  74: INSERT [dbo].[Resource] ([Key], [Culture], [Value]) VALUES (N'View_AccountRegister_Message', N'en-US', N'Create a new account.')
  75: GO
  76: INSERT [dbo].[Resource] ([Key], [Culture], [Value]) VALUES (N'View_AccountRegister_Message', N'zh-CN', N'????????')
  77: GO
  78: INSERT [dbo].[Resource] ([Key], [Culture], [Value]) VALUES (N'View_ExternalLoginsListPartial_MessageInfo', N'en-US', N'There are no external authentication services configured. See <a href="http://go.microsoft.com/fwlink/?LinkId=252166">this article</a> for details on setting up this ASP.NET application to support logging in via external services.')
  79: GO
  80: INSERT [dbo].[Resource] ([Key], [Culture], [Value]) VALUES (N'View_ExternalLoginsListPartial_MessageInfo', N'zh-CN', N'???????????????????ASP.NET?????????????????,????<a href="http://go.microsoft.com/fwlink/?LinkId=252166">??</a>?')
  81: GO
  82: INSERT [dbo].[Resource] ([Key], [Culture], [Value]) VALUES (N'View_ExternalLoginsListPartial_SocialLoginList', N'en-US', N'Log in using another service')
  83: GO
  84: INSERT [dbo].[Resource] ([Key], [Culture], [Value]) VALUES (N'View_ExternalLoginsListPartial_SocialLoginList', N'zh-CN', N'?????????')
  85: GO
  86: INSERT [dbo].[Resource] ([Key], [Culture], [Value]) VALUES (N'View_HomeAbout_Title', N'en-US', N'About')
  87: GO
  88: INSERT [dbo].[Resource] ([Key], [Culture], [Value]) VALUES (N'View_HomeAbout_Title', N'zh-CN', N'??')
  89: GO
  90: INSERT [dbo].[Resource] ([Key], [Culture], [Value]) VALUES (N'View_HomeContact_Title', N'en-US', N'Contact')
  91: GO
  92: INSERT [dbo].[Resource] ([Key], [Culture], [Value]) VALUES (N'View_HomeContact_Title', N'zh-CN', N'????')
  93: GO
  94: INSERT [dbo].[Resource] ([Key], [Culture], [Value]) VALUES (N'View_HomeIndex_Title', N'en-US', N'Home Page')
  95: GO
  96: INSERT [dbo].[Resource] ([Key], [Culture], [Value]) VALUES (N'View_HomeIndex_Title', N'zh-CN', N'??')
  97: GO
  98: INSERT [dbo].[Resource] ([Key], [Culture], [Value]) VALUES (N'View_HomIndex_Featured', N'en-US', N'To learn more about ASP.NET MVC visit <a href="http://asp.net/mvc" title="ASP.NET MVC Website">http://asp.net/mvc</a>. The page features <mark>videos, tutorials, and samples</mark> to help you get the most from ASP.NET MVC. If you have any questions about ASP.NET MVC visit <a href="http://forums.asp.net/1146.aspx/1?MVC" title="ASP.NET MVC Forum">our forums</a>.')
  99: GO
 100: INSERT [dbo].[Resource] ([Key], [Culture], [Value]) VALUES (N'View_HomIndex_Featured', N'zh-CN', N'???????ASP.NET MVC??????<a href="http://asp.net/mvc" title="ASP.NET MVC??">http://asp.net/mvc</a>??????<mark>??,?????</mark>,??????????ASP.NET MVC???????????ASP.NET MVC???,??????<a href="http://forums.asp.net/1146.aspx/1?MVC" title="ASP.NET MVC??">??</a>?')
 101: GO
 102: INSERT [dbo].[Resource] ([Key], [Culture], [Value]) VALUES (N'View_HomIndex_Suggest', N'en-US', N'We suggest the following:')
 103: GO
 104: INSERT [dbo].[Resource] ([Key], [Culture], [Value]) VALUES (N'View_HomIndex_Suggest', N'zh-CN', N'????:')
 105: GO
 106: INSERT [dbo].[Resource] ([Key], [Culture], [Value]) VALUES (N'View_HomIndex_Suggest_1_Title', N'en-US', N'Getting Started')
 107: GO
 108: INSERT [dbo].[Resource] ([Key], [Culture], [Value]) VALUES (N'View_HomIndex_Suggest_1_Title', N'zh-CN', N'??')
 109: GO
 110: INSERT [dbo].[Resource] ([Key], [Culture], [Value]) VALUES (N'View_HomIndex_Suggest_1_Val', N'en-US', N'ASP.NET MVC gives you a powerful, patterns-based way to build dynamic websites that enables a clean separation of concerns and that gives you full control over markup for enjoyable, agile development. ASP.NET MVC includes many features that enable fast, TDD-friendly development for creating sophisticated applications that use the latest web standards. <a href="http://go.microsoft.com/fwlink/?LinkId=245151">Learn more...</a>')
 111: GO
 112: INSERT [dbo].[Resource] ([Key], [Culture], [Value]) VALUES (N'View_HomIndex_Suggest_1_Val', N'zh-CN', N'ASP.NET MVC?????????????????????????,???????????,????,?????????????? ASP.NET MVC???????,????????????,?????Web??,TDD??????<a href="http://go.microsoft.com/fwlink/?LinkId=245151">????…</a>')
 113: GO
 114: INSERT [dbo].[Resource] ([Key], [Culture], [Value]) VALUES (N'View_HomIndex_Suggest_2_Title', N'en-US', N'Add NuGet packages and jump-start your coding')
 115: GO
 116: INSERT [dbo].[Resource] ([Key], [Culture], [Value]) VALUES (N'View_HomIndex_Suggest_2_Title', N'zh-CN', N'??NuGet???,??????')
 117: GO
 118: INSERT [dbo].[Resource] ([Key], [Culture], [Value]) VALUES (N'View_HomIndex_Suggest_2_Val', N'en-US', N'NuGet makes it easy to install and update free libraries and tools. <a href="http://go.microsoft.com/fwlink/?LinkId=245153">Learn more...</a>')
 119: GO
 120: INSERT [dbo].[Resource] ([Key], [Culture], [Value]) VALUES (N'View_HomIndex_Suggest_2_Val', N'zh-CN', N'NuGet??????????????????????<a href="http://go.microsoft.com/fwlink/?LinkId=245153">????…</a>')
 121: GO
 122: INSERT [dbo].[Resource] ([Key], [Culture], [Value]) VALUES (N'View_HomIndex_Suggest_3_Title', N'en-US', N'Find Web Hosting')
 123: GO
 124: INSERT [dbo].[Resource] ([Key], [Culture], [Value]) VALUES (N'View_HomIndex_Suggest_3_Title', N'zh-CN', N'??????')
 125: GO
 126: INSERT [dbo].[Resource] ([Key], [Culture], [Value]) VALUES (N'View_HomIndex_Suggest_3_Val', N'en-US', N'You can easily find a web hosting company that offers the right mix of features and price for your applications. <a href="http://go.microsoft.com/fwlink/?LinkId=245157">Learn more...</a>')
 127: GO
 128: INSERT [dbo].[Resource] ([Key], [Culture], [Value]) VALUES (N'View_HomIndex_Suggest_3_Val', N'zh-CN', N'???????????Web????,?????????????????????<a href="http://go.microsoft.com/fwlink/?LinkId=245157">????…</a>')
 129: GO
 130: INSERT [dbo].[Resource] ([Key], [Culture], [Value]) VALUES (N'View_Layout_LogoHere', N'en-US', N'your logo here')
 131: GO
 132: INSERT [dbo].[Resource] ([Key], [Culture], [Value]) VALUES (N'View_Layout_LogoHere', N'zh-CN', N'???????')
 133: GO
 134: INSERT [dbo].[Resource] ([Key], [Culture], [Value]) VALUES (N'View_Layout_Title', N'en-US', N'My ASP.NET MVC Application')
 135: GO
 136: INSERT [dbo].[Resource] ([Key], [Culture], [Value]) VALUES (N'View_Layout_Title', N'zh-CN', N'??ASP.NET MVC????')
 137: GO
 138: INSERT [dbo].[Resource] ([Key], [Culture], [Value]) VALUES (N'View_LoginPartial_Login', N'en-US', N'Log in')
 139: GO
 140: INSERT [dbo].[Resource] ([Key], [Culture], [Value]) VALUES (N'View_LoginPartial_Login', N'zh-CN', N'??')
 141: GO
 142: INSERT [dbo].[Resource] ([Key], [Culture], [Value]) VALUES (N'View_LoginPartial_Logoff', N'en-US', N'Log off')
 143: GO
 144: INSERT [dbo].[Resource] ([Key], [Culture], [Value]) VALUES (N'View_LoginPartial_Logoff', N'zh-CN', N'??')
 145: GO
 146: INSERT [dbo].[Resource] ([Key], [Culture], [Value]) VALUES (N'View_LoginPartial_Register', N'en-US', N'Register')
 147: GO
 148: INSERT [dbo].[Resource] ([Key], [Culture], [Value]) VALUES (N'View_LoginPartial_Register', N'zh-CN', N'??')
 149: GO
 150: INSERT [dbo].[Resource] ([Key], [Culture], [Value]) VALUES (N'View_PageName_About', N'en-US', N'About')
 151: GO
 152: INSERT [dbo].[Resource] ([Key], [Culture], [Value]) VALUES (N'View_PageName_About', N'zh-CN', N'??')
 153: GO
 154: INSERT [dbo].[Resource] ([Key], [Culture], [Value]) VALUES (N'View_PageName_Contact', N'en-US', N'Contact')
 155: GO
 156: INSERT [dbo].[Resource] ([Key], [Culture], [Value]) VALUES (N'View_PageName_Contact', N'zh-CN', N'????')
 157: GO
 158: INSERT [dbo].[Resource] ([Key], [Culture], [Value]) VALUES (N'View_PageName_Home', N'en-US', N'Home')
 159: GO
 160: INSERT [dbo].[Resource] ([Key], [Culture], [Value]) VALUES (N'View_PageName_Home', N'zh-CN', N'??')
 161: GO

Then we need to add the node-sqlserver module in our local repository. As I mentioned in the previous post the node-sqlserver works with SQL Server and WASD. But there’s a problem if we are using NPM to install it. If you remembered, I specified that when NPM installed node-sqlserver it will build some C++ code by Python. The output binary depends on the local machine and Python whether it’s x86 or x64. If our local machine was x86 then this is no problem. But if our local machine is x64, the node-sqlserver module cannot be used on WAWS, since in WAWS all website are hosted in IIS in x86 WOW mode.

One solution is to change our development machine to x86, which may not be acceptable since x64 is preferred for other Windows Azure services development such as WASD and WACS.

Or maybe we can find a x86 machine to download and compile a x86 version of node-sqlserver for us, then copy it to our working PC.

Or we can download the x86 version node-sqlserver from Microsoft, which named “Microsoft Driver for Node.JS for SQL Server Preview” found here. Then follow its instruction we could install and copy the “node-sqlserver” folder under the “node_modules” folder in our repository.

Now we can use the similar source code in previous post to work with WASD, just need to change the connection string. The code would be like this.

   1: var express = require("express");
   2: var sql = require("node-sqlserver");
   3:  
   4: var connectionString = "Driver={SQL Server Native Client 10.0};Server=tcp:{YOUR SERVER NAME}.database.windows.net,1433;Database=nodejssample;Uid={YOUR LOGIN}@{YOUR SERVER NAME};Pwd={YOUR PASSWORD};Encrypt=yes;Connection Timeout=30;";
   5: var port = process.env.PORT
   6:  
   7: var app = express();
   8:  
   9: app.configure(function () {
  10:     app.use(express.bodyParser());
  11: });
  12:  
  13: app.get("/", function(req, res) {
  14:     sql.open(connectionString, function(err, conn) {
  15:         if(err) {
  16:             console.log(err);
  17:             res.send(500, "Cannot open connection.");
  18:         }
  19:         else {
  20:             conn.queryRaw("SELECT * FROM [Resource]", function(err, results) {
  21:                 if(err) {
  22:                     console.log(err);
  23:                     res.send(500, "Cannot retrieve records.");
  24:                 }
  25:                 else {
  26:                     res.json(results);
  27:                 }
  28:             });
  29:         }
  30:     });
  31: });
  32:  
  33: app.get("/text/:key/:culture", function(req, res) {
  34:     sql.open(connectionString, function(err, conn) {
  35:         if(err) {
  36:             console.log(err);
  37:             res.send(500, "Cannot open connection.");
  38:         }
  39:         else {
  40:             var key = req.params.key;
  41:             var culture = req.params.culture;
  42:             var command = "SELECT * FROM [Resource] WHERE [Key] = '" + key + "' AND [Culture] = '" + culture + "'";
  43:             conn.queryRaw(command, function(err, results) {
  44:                 if(err) {
  45:                     console.log(err);
  46:                     res.send(500, "Cannot retrieve records.");
  47:                 }
  48:                 else {
  49:                     res.json(results);
  50:                 }
  51:             });
  52:         }
  53:     });
  54: });
  55:  
  56: app.get("/sproc/:key/:culture", function(req, res) {
  57:     sql.open(connectionString, function(err, conn) {
  58:         if(err) {
  59:             console.log(err);
  60:             res.send(500, "Cannot open connection.");
  61:         }
  62:         else {
  63:             var key = req.params.key;
  64:             var culture = req.params.culture;
  65:             var command = "EXEC GetItem '" + key + "', '" + culture + "'";
  66:             conn.queryRaw(command, function(err, results) {
  67:                 if(err) {
  68:                     console.log(err);
  69:                     res.send(500, "Cannot retrieve records.");
  70:                 }
  71:                 else {
  72:                     res.json(results);
  73:                 }
  74:             });
  75:         }
  76:     });
  77: });
  78:  
  79: app.post("/new", function(req, res) {
  80:     var key = req.body.key;
  81:     var culture = req.body.culture;
  82:     var val = req.body.val;
  83:     
  84:     sql.open(connectionString, function(err, conn) {
  85:         if(err) {
  86:             console.log(err);
  87:             res.send(500, "Cannot open connection.");
  88:         }
  89:         else {
  90:             var command = "INSERT INTO [Resource] VALUES ('" + key + "', '" + culture + "', N'" + val + "')";
  91:             conn.queryRaw(command, function(err, results) {
  92:                 if(err) {
  93:                     console.log(err);
  94:                     res.send(500, "Cannot retrieve records.");
  95:                 }
  96:                 else {
  97:                     res.send(200, "Inserted Successful");
  98:                 }
  99:             });
 100:         }
 101:     });
 102: });
 103:  
 104: app.listen(port);

The connection string can be found in our WASD page in developer portal. In Node.js we need to use the ODBC connection string and make sure change the password before commit and sync.

Save the file and in GitHub window commit and sync it. Our website will be deployed automatically.

image

If we changed a little bit of our C# console application then we can test the post function in our Node.js application hosted on WAWS. The updated C# console code would like this, just changed the remote URL.

   1: static void Main(string[] args)
   2: {
   3:     var key = args[0];
   4:     var culture = args[1];
   5:     var val = args[2];
   6:  
   7:     var req = HttpWebRequest.Create("http://nodejssample.azurewebsites.net/new");
   8:     req.ContentType = "application/x-www-form-urlencoded";
   9:     req.Method = WebRequestMethods.Http.Post;
  10:  
  11:     var param = string.Format("key={0}&culture={1}&val={2}", key, culture, val);
  12:     var bytes = System.Text.Encoding.UTF8.GetBytes(param);
  13:     req.ContentLength = bytes.Length;
  14:     using(var stream = req.GetRequestStream())
  15:     {
  16:         stream.Write(bytes, 0, bytes.Length);
  17:     }
  18:  
  19:     var res = req.GetResponse();
  20:     using (var sr = new StreamReader(res.GetResponseStream()))
  21:     {
  22:         Console.WriteLine(sr.ReadToEnd());
  23:     }
  24:     Console.ReadKey();
  25: }

Then run this application to add some records in WASD.

image

And then back to the browser and find the items we had just inserted.

image

 

Summary

In this post I demonstrated on how to host Node.js website on Windows Azure Web Site. It’s very simple and easy to deploy by using the Git command client and the new GitHub GUI.

I also described how to use Windows Azure SQL Database from Node.js on Windows Azure Web Site. Make sure you imported the right version of sqlserver.node. For better development and cloud environment we can have two node-sqlserver modules, x86 version in folder “node-sqlserver-x86” while x64 in “node-sqlserver-x64”. Then we can import the x64 on local development and changed it to “node-sqlserver-x86” before commit and sync to azure.

In Windows Azure there are some other services besides SQL Database such as Storage, Service Bus, etc.. Almost all Windows Azure services can be used by Node.js through another module named “azure”, which is Windows Azure Node.js SDK. In the next post I will demonstrate on how to host our Node.js application on Windows Azure Cloud Service Worker Role, how to consume the Storage Service and how to retrieve the Cloud Service configuration.

 

Hope this helps,

Shaun

All documents and related graphics, codes are provided "AS IS" without warranty of any kind.
Copyright © Shaun Ziyan Xu. This work is licensed under the Creative Commons License.

Comments

No comments posted yet.
Post A Comment
Title:
Name:
Email:
Comment:
Verification: