I'm new to node and express but I'm having an issue when I host my node web app in windows azure which by the way works completely fine on localhost. I just get a blank white screen.
this is my:
server.js
var root = require('root');
var github = require('github-auth');
var express = require('express');
var path = require('path');
// var app = root();
var app = express();
var gh = github('clientid', 'clientsecret, {
organization: 'my-org',
team: 'my-team',
autologin: true // This automatically redirects you to github to login
});
app.get('/login', gh.login);
app.use(express.static(__dirname + '/'));
app.all('*', gh.authenticate);
app.all('*', function(req, res, next) {
if (!req.github) return res.sendFile(__dirname + '/login.html');
if (!req.github.authenticated) res.sendFile(path.join(__dirname+'/kickout.html'));
next();
});
app.get('/main',function(req,res){
res.sendFile(path.join(__dirname+'/main.html'));
});
app.get('/about',function(req,res){
res.sendFile('/kickout.html');
});
app.listen(3000);
console.log("Running at Port 3000");
Node.js application running on Azure Web Apps Service, is hosted on IIS handled mapping via IISNode, which gives a Named Pipe to receive the incoming requests, not a TCP port like you would use when running locally.
This Named Pipe has been defined as the port in Node.js runtime on Azure Web Apps. You can define the port in your app link: process.env.PORT || 3000, with which your app can run on Azure or locally.
And you may check whether there is a file web.config in your root directory, which is the configurations of IIS of your application. It should have the similar content:
<configuration>
<system.webServer>
<handlers>
<!-- indicates that the app.js file is a node.js application to be handled by the iisnode module -->
<add name="iisnode" path="server.js" verb="*" modules="iisnode"/>
</handlers>
<rewrite>
<rules>
<!-- Don't interfere with requests for node-inspector debugging -->
<rule name="NodeInspector" patternSyntax="ECMAScript" stopProcessing="true">
<match url="^server.js\/debug[\/]?" />
</rule>
<!-- First we consider whether the incoming URL matches a physical file in the /public folder -->
<rule name="StaticContent">
<action type="Rewrite" url="public{REQUEST_URI}"/>
</rule>
<!-- All other URLs are mapped to the Node.js application entry point -->
<rule name="DynamicContent">
<conditions>
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="True"/>
</conditions>
<action type="Rewrite" url="server.js"/>
</rule>
</rules>
</rewrite>
<!-- You can control how Node is hosted within IIS using the following options -->
<!--<iisnode
node_env="%node_env%"
nodeProcessCommandLine=""%programfiles%\nodejs\node.exe""
nodeProcessCountPerApplication="1"
maxConcurrentRequestsPerProcess="1024"
maxNamedPipeConnectionRetry="3"
namedPipeConnectionRetryDelay="2000"
maxNamedPipeConnectionPoolSize="512"
maxNamedPipePooledConnectionAge="30000"
asyncCompletionThreadCount="0"
initialRequestBufferSize="4096"
maxRequestBufferSize="65536"
watchedFiles="*.js"
uncFileChangesPollingInterval="5000"
gracefulShutdownTimeout="60000"
loggingEnabled="true"
logDirectoryNameSuffix="logs"
debuggingEnabled="true"
debuggerPortRange="5058-6058"
debuggerPathSegment="debug"
maxLogFileSizeInKB="128"
appendToExistingLog="false"
logFileFlushInterval="5000"
devErrorsEnabled="true"
flushResponse="false"
enableXFF="false"
promoteServerVars=""
/>-->
<iisnode watchedFiles="*.js;node_modules\*;routes\*.js;views\*.jade"/>
</system.webServer>
</configuration>
When hosting Node.js apps via Azure Web Apps, you need to modify your port initialization as shown in the following simplified sample:
var http = require('http'),
port = process.env.PORT || 1337;
http.createServer(function(req, res) {
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end('Hello World\n');
}).listen(port);
When running locally, the literal port will be used (e.g. 1337 above), but when running in Azure a port will be assigned to process.env.port by the hosting platform and that will be used. You can find a complete walkthrough on deploying a Node.js app here. When running in a WebApp, a technology called IIS Node is used to run your Node app. More details on that can be found here.
Related
I have developed a chat application with nodejs. Currently, I am using the chat server hosted from a command prompt. This chat server is not bound to any domain name. I want it to bind to a domain with IIS. I have also tried to install IIS Node but could not get through. I have all my chat code in chatroom.js file, there is no HTML file to be rendered. I am not clear how to host it with IIS Node. I am using IIS 8 on Windows 8. The error I am get when hit the URL : http://localhost:3004/chatRoom.js
HTTP Error 500.21 - Internal Server Error
Handler "iisnode-socketio" has a bad module "iisnode" in its module list
Below is my web.config :
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0"/>
</system.web>
<system.webServer>
<!-- indicates that the server-faye.js and server-socketio.js files are node.js applications
to be handled by the iisnode module -->
<handlers>
<add name="iisnode-socketio" path="chatRoom.js" verb="*" modules="iisnode" />
</handlers>
<!-- indicate that all strafic the URL paths beginning with 'socket.io' should be
redirected to the server-socketio.js node.js application to avoid IIS attempting to
serve that content using other handlers (e.g. static file handlers)
-->
<globalModules>
<add name="iisnode" image="C:\Program Files (x86)\iisnode-express\iisnode.dll" />
</globalModules>
<rewrite>
<rules>
<clear />
<rule name="cdw">
<match url="/*" />
<action type="Rewrite" url="chatRoom.js" />
</rule>
</rules>
</rewrite>
<!-- disable the IIS websocket module to allow node.js to provide its own
WebSocket implementation -->
<webSocket enabled="false" />
</system.webServer>
</configuration>
node server side code looks as follows :
var express = require('express'),
http = require('http'),
app = express(),
server = http.createServer(app),
io = require('socket.io').listen(server),
Room = require('./room.js'),
defaultValues = require('./default.js'),
_ = require('underscore')._;
var request = require('request');
//require('request').debug = true; // uncomment for debugging
app.use('/', express.static(__dirname + '/public'));
server.listen(process.env.PORT);
app.get('/', function (req, res) {
res.sendFile(__dirname + '/public/indexroom.html')
});
Please let me know if I am missing anything.
I imported the git socket.io chat room project! The code works normally with http = require ('http') but when exchanging for https = require ('https') my server responds with error 500 http
var express = require('express')
, app = express()
// , http = require('http')
, https = require('https')
, fs = require('fs')
, privateKey = fs.readFileSync('HTTPS_Permissions/key.key', 'utf8')
, certificate = fs.readFileSync('HTTPS_Permissions/cert.cert', 'utf8')
, credentials = {key: privateKey, cert: certificate}
, httpsServer = https.createServer(credentials, app)
// , httpServer = http.createServer(app)
, io = require('socket.io').listen(httpsServer)
//, port = process.env.PORT || 8080
, port = process.env.PORT
httpsServer.listen(port, function () {
console.log('Server listening on port %d', port);
});
//httpServer.listen(port);
// routing
app.get('/', function (req, res) {
res.sendfile(__dirname + '/index.html');
});
I followed the project you shared in the comment,it works on my side.
web.config
<?xml version="1.0" encoding="utf-8"?>
<!--
This configuration file is required if iisnode is used to run node processes behind
IIS or IIS Express. For more information, visit:
https://github.com/tjanczuk/iisnode/blob/master/src/samples/configuration/web.config
-->
<configuration>
<system.webServer>
<!-- Visit http://blogs.msdn.com/b/windowsazure/archive/2013/11/14/introduction-to-websockets-on-windows-azure-web-sites.aspx for more information on WebSocket support -->
<webSocket enabled="false" />
<handlers>
<!-- Indicates that the server.js file is a node.js site to be handled by the iisnode module -->
<add name="iisnode" path="app.js" verb="*" modules="iisnode"/>
</handlers>
<rewrite>
<rules>
<!-- Do not interfere with requests for node-inspector debugging -->
<rule name="NodeInspector" patternSyntax="ECMAScript" stopProcessing="true">
<match url="^app.js\/debug[\/]?" />
</rule>
<!-- First we consider whether the incoming URL matches a physical file in the /public folder -->
<rule name="StaticContent">
<action type="Rewrite" url="public{REQUEST_URI}"/>
</rule>
<!-- All other URLs are mapped to the node.js site entry point -->
<rule name="DynamicContent">
<conditions>
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="True"/>
</conditions>
<action type="Rewrite" url="app.js"/>
</rule>
</rules>
</rewrite>
<!-- 'bin' directory has no special meaning in node.js and apps can be placed in it -->
<security>
<requestFiltering>
<hiddenSegments>
<remove segment="bin"/>
</hiddenSegments>
</requestFiltering>
</security>
<!-- Make sure error responses are left untouched -->
<httpErrors existingResponse="PassThrough" />
<!--
You can control how Node is hosted within IIS using the following options:
* watchedFiles: semi-colon separated list of files that will be watched for changes to restart the server
* node_env: will be propagated to node as NODE_ENV environment variable
* debuggingEnabled - controls whether the built-in debugger is enabled
See https://github.com/tjanczuk/iisnode/blob/master/src/samples/configuration/web.config for a full list of options
-->
<iisnode watchedFiles="web.config;*.js"/>
</system.webServer>
</configuration>
If you throw the index.html into public folder which is created by yourself under wwwroot/ directly, you need to add the below code into your code based on this article.
app.use(express.static('public'))
I tested for that.
Update Answer:
I also turn on the Web Sockets Option.
I have the basic express 4 app running locally using the node provided web server.
I attempted to view/edit in Webmatrix and use IIS so I could then upload to Azure as a node app. Azure's template uses older versions of node and express.
When run from Webmatrix using IIS - and when published to Azure, I receive the following:
HRESULT: 0x2
HTTP status: 500
HTTP reason: Internal Server Error
I believe the issue is somehow related to the web.config file but all articles and fixes I've found are dated and have not resolved the issue.
My web.config file:
<configuration>
<system.webServer>
<handlers>
<!-- indicates that the app.js file is a node.js application to be handled by the iisnode module -->
<add name="iisnode" path="app.js" verb="*" modules="iisnode" />
</handlers>
<rewrite>
<rules>
<!-- Don't interfere with requests for node-inspector debugging -->
<rule name="NodeInspector" patternSyntax="ECMAScript" stopProcessing="true">
<match url="^app.js\/debug[\/]?" />
</rule>
<!-- First we consider whether the incoming URL matches a physical file in the /public folder -->
<rule name="StaticContent">
<action type="Rewrite" url="public{REQUEST_URI}" />
</rule>
<!-- All other URLs are mapped to the Node.js application entry point -->
<rule name="DynamicContent">
<conditions>
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="True" />
</conditions>
<action type="Rewrite" url="app.js" />
</rule>
</rules>
</rewrite>
<!-- You can control how Node is hosted within IIS using the following options -->
<!--
<iisnode
node_env="%node_env%"
nodeProcessCountPerApplication="1"
maxConcurrentRequestsPerProcess="1024"
maxNamedPipeConnectionRetry="3"
namedPipeConnectionRetryDelay="2000"
maxNamedPipeConnectionPoolSize="512"
maxNamedPipePooledConnectionAge="30000"
asyncCompletionThreadCount="0"
initialRequestBufferSize="4096"
maxRequestBufferSize="65536"
watchedFiles="*.js"
uncFileChangesPollingInterval="5000"
gracefulShutdownTimeout="60000"
loggingEnabled="true"
logDirectoryNameSuffix="logs"
debuggingEnabled="true"
debuggerPortRange="5058-6058"
debuggerPathSegment="debug"
maxLogFileSizeInKB="128"
appendToExistingLog="false"
logFileFlushInterval="5000"
devErrorsEnabled="true"
flushResponse="false"
enableXFF="false"
promoteServerVars=""
/>
-->
</system.webServer>
</configuration>
I've contacted the Azure team and they've started a discussion but I have more faith in what stackoverflow users can provide.
#Matthew,
here is my guess, i think you didn`t config your app to listen to the right port when deploy to azure app service. you will need to do something similar to below code to get port number from enviroment valirable "process.env.port"
var app = require('express')();
var port = process.env.port || 8080; // 8080 for local or whatever number u want
var listener = app.listen(port, function(){
console.log('Listening on port ' + port);
});
I've been trying to run a node application on iisnode. this app runs on node.js smoothly and has no problem. however, i need to integrate this app to an asp.net application hence i've been trying to run this app on iis using iisnode! but i've been facing some difficulties! i was wondering is there anything that need to be changed in config or server.js file to make it work ?
thanks !
The only required change in node app will be port number - use process.env.PORT value instead of specific numeric in you server.js/app.js as stated in the official /src/samples/express/hello.js (notice the last line):
var express = require('express');
var app = express.createServer();
app.get('/node/express/myapp/foo', function (req, res) {
res.send('Hello from foo! [express sample]');
});
app.get('/node/express/myapp/bar', function (req, res) {
res.send('Hello from bar! [express sample]');
});
app.listen(process.env.PORT);
Also make sure that asp.net's web.config have sections for node (taken from /src/samples/express/web.config):
<configuration>
<system.webServer>
<!-- indicates that the hello.js file is a node.js application
to be handled by the iisnode module -->
<handlers>
<add name="iisnode" path="hello.js" verb="*" modules="iisnode" />
</handlers>
<!-- use URL rewriting to redirect the entire branch of the URL namespace
to hello.js node.js application; for example, the following URLs will
all be handled by hello.js:
http://localhost/node/express/myapp/foo
http://localhost/node/express/myapp/bar
-->
<rewrite>
<rules>
<rule name="myapp">
<match url="myapp/*" />
<action type="Rewrite" url="hello.js" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
Errors:
Trying to access http://localhost/appDirectory/socket.io gives:
Cannot GET /appDirectory/socket.io
Or to put it another way when trying to load the client file on the page I get this error:
GET http://localhost/appDirectory/socket.io/socket.io.js 404 (Not Found)
If I load the client file as static content the connect line produces this error:
GET http://localhost/appDirectory/socket.io/1/?t=1365535131937 404 (Not Found)
Server code:
var express = require('express'),
namespace = require('express-namespace'),
routes = require('./routes'),
http = require('http'),
app = express(),
server = app.listen(process.env.PORT),
io = require('socket.io').listen(server);
var appDir = '/appDirectory';
app.configure(function(){
app.set('env', process.env.NODE_ENV || 'development');
app.set('/views', __dirname + '/views');
app.set('view engine', 'jade');
app.use(app.router);
app.use(appDir, require('stylus').middleware(__dirname + '/public'));
app.use(appDir, express.static(path.join(__dirname, '/public')));
});
app.get(appDir + '/', routes.index);
io.sockets.on('connection', function (socket) {
socket.emit('message', 'lol');
});
Client code:
<script src="/appDirectory/socket.io/socket.io.js"></script>
<script type="text/javascript">
var socket = io.connect(appDir, { resource: appDir.substring(1) + '/socket.io' });
socket.on('connect', function () {
console.log('connected');
});
</script>
The web config file that's getting this to work is...
Web.config:
<configuration>
<system.webServer>
<handlers>
<add name="iisnode" path="app.js" verb="*" modules="iisnode" />
</handlers>
<iisnode loggingEnabled="true" debuggingEnabled="true" debuggerPathSegment="debug" />
<rewrite>
<rules>
<clear />
<rule name="Debug" patternSyntax="Wildcard" stopProcessing="true">
<match url="app.js/debug*" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false" />
<action type="None" />
</rule>
<rule name="app" patternSyntax="Wildcard">
<match url="*" negate="false" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false" />
<action type="Rewrite" url="app.js" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
My gut feeling is that the express routing is interfering with the socket.io routing or that the socket.io routing is not compatible with the virtual directory. I did see some mention of namespacing with socket.io and I did try the following...
io.of(appDir).on('connection', function (socket) {
socket.emit('message', 'lol');
});
But that didn't seem to fix the problem.
I have tried a number of different things on the client code side but I don't think that is the root problem or the http://localhost/appDirectory/socket.io/socket.io.js would be working.
The application is running as a virtual directory and is built on:
- node.js 0.10.3 for windows
- iis 7
- iisnode 0.2.4
- express.js 3.0.0rc1
- jade
- socket.io
The module "express namespace" seems to make things work.
I am aware that iisnode was "designed" to be run as a separate site and I'm also aware that express doesn't like being in a virtual directory, but I am pretty sure this is possible.
Interesting update!
Changing the line:
io = require('socket.io').listen(server);
To:
io = require('socket.io').listen(server, { resource: appDir + '/socket.io' });
Causes the iis worker process w3wp.exe to crash...
As seen here http://i.imgur.com/65RGia3.png?1
However the url http://localhost/appDirectory/socket.io then seems to work.
Failed attempts at fixing this FYI:
adding the web.config setting for iisnode nodeProcessCountPerApplication="1"
Possible solution:
If you are stuggling with this same issue, I found this which might help you...
http://tomasz.janczuk.org/2013/01/hosting-socketio-websocket-apps-in-iis.html
It looks like you're on the right track. Using the following configuration, it works for me (not using IIS, though):
// server
io = require('socket.io').listen(server, { resource : '/appDirectory/socket.io' });
// client
<script src="/appDirectory/socket.io/socket.io.js"></script>
...
var socket = io.connect('', { resource: 'appDirectory/socket.io' });
I wonder why your IIS process is crashing, could you post the image elsewhere (Dropbox, free image hoster) perhaps?
A little bit of a stab in the dark, but if you're using Express 3.x, your problem may be that you're using the older Express 2.x syntax for hooking up Socket.io with Express.
See: https://github.com/visionmedia/express/wiki/Migrating-from-2.x-to-3.x#socketio-compatibility for the new integration method.