I'm trying to create a cluster server with socket.io and express.js I'm following various tutorials on the internet as well on youtube.
What I have at the moment is this code in my app.js:
var cluster = require('cluster');
if (cluster.isMaster) {
var cpuCount = require('os').cpus().length;
var workers = [];
for (var i = 0; i < cpuCount; i++) {
workers[i] = cluster.fork();
}
cluster.on('exit', function (worker){
for (var i = 0; i < workers.length; i++) {
if (worker.process.pid === workers[i].process.pid) {
workers.splice(i, 1);
}
}
for (var i = 0; i < cpuCount - workers.length; i++) {
workers.push(cluster.fork());
}
});
} else {
/**
* Module dependencies.
*/
var express = require('express');
var routes = require('./routes');
var http = require('http');
var path = require('path');
var app = express();
app.set('port', process.env.PORT || 3000);
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(app.router);
app.use(express.static(path.join(__dirname, 'public')));
// development only
if ('development' == app.get('env')) {
app.use(express.errorHandler());
}
app.get('/', routes.index);
var server = http.createServer(app);
var io = require('socket.io').listen(app.get('port'));
}
When I go to http://localhost:3000/ I get the response:
Welcome to socket.io.
In my previous test scripts I didnt have this issue and my jade templates were being rendered fine. Could someone explain why is this happenning?
Furthermore in my routes directory I have the script: index.js with this code:
/*
* GET home page.
*/
exports.index = function(req, res){
res.render('index', { title: 'Express' });
};
Finally in my views folder I have layout.jade with:
doctype 5
html
head
title= title
link(rel='stylesheet', href='/stylesheets/style.css')
body
block content
and index.jade with:
extends layout
block content
h1= title
p Welcome to #{title}
It seems that the problem was in the final lines of app.js
this fixes the issue:
var server = http.createServer(app);
var io = require('socket.io').listen(server);
server.listen(app.get('port'));
Sorry for any inconvenience.
Related
I did read all the other topics but none of the solutions solved my problem.
I write npm start and the server is working as it should but app-root does not it seems like it does not load the client (Angular 2 app).
I just get an empty html page with:
Loading...
(look at my html file down the page)
any idea what can cause it - or any suggested solution ?
Thank you.
app.js
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var mongoose = require('mongoose')
//Set up default mongoose connection
var mongoDB = 'mongodb://localhost/beatblocks';
// Get Mongoose to use the global promise library
mongoose.Promise = global.Promise;
mongoose.connect(mongoDB, function(err) {
if (err){
console.log("error connecting to db...")
}
console.log("connected to database...");
});
// Load Songs Model
require('./models/songs');
const songs = mongoose.model('songs');
// Load Locations Model
require('./models/locations');
const locations = mongoose.model('locations');
// Load users Model
require('./models/users');
const users = mongoose.model('users');
var routeIndex = require('./routes/index');
var routeSongs = require('./routes/songs');
var routeUsers = require('./routes/users');
//var routeLocations = require('./routes/locations');
var app = express();
var router = express.Router();
// Set Static Folder
app.use(express.static(path.join(__dirname, 'views')));
app.use(express.static(path.join(__dirname, '/client/dist')));
app.use(express.static(path.join(__dirname, 'client/src')));
//View Engine
app.engine('ejs', require('ejs').renderFile);
app.set('view engine', 'ejs');
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use('/', routeIndex);
app.use('/songs', routeSongs);
app.use('/users', routeUsers);
//app.use('/locations', routeLocations);
module.exports = app;
www.js
#!/usr/bin/env node
/**
* Module dependencies.
*/
var app = require('../app');
var debug = require('debug')('beatblocksweb:server');
var http = require('http');
/**
* Get port from environment and store in Express.
*/
var port = normalizePort(process.env.PORT || '3000');
app.set('port', port);
/**
* Create HTTP server.
*/
var server = http.createServer(app);
/**
* Listen on provided port, on all network interfaces.
*/
app.listen(port, function(){
console.log('Server started on port '+port);
});
server.on('error', onError);
server.on('listening', onListening);
/**
* Normalize a port into a number, string, or false.
*/
function normalizePort(val) {
var port = parseInt(val, 10);
if (isNaN(port)) {
// named pipe
return val;
}
if (port >= 0) {
// port number
return port;
}
return false;
}
/**
* Event listener for HTTP server "error" event.
*/
function onError(error) {
if (error.syscall !== 'listen') {
throw error;
}
var bind = typeof port === 'string'
? 'Pipe ' + port
: 'Port ' + port;
// handle specific listen errors with friendly messages
switch (error.code) {
case 'EACCES':
console.error(bind + ' requires elevated privileges');
process.exit(1);
break;
case 'EADDRINUSE':
console.error(bind + ' is already in use');
process.exit(1);
break;
default:
throw error;
}
}
/**
* Event listener for HTTP server "listening" event.
*/
function onListening() {
var addr = server.address();
var bind = typeof addr === 'string'
? 'pipe ' + addr
: 'port ' + addr.port;
debug('Listening on ' + bind);
}
my index.html :
<html>
<head>
<title>Beat Blocks</title>
</head>
<body>
<app-root>Loading...</app-root>
<app-header></app-header>
</body>
</html>
my project :
I'm trying to parse select (dropdown) box element on form post.
Request body contains only 'txt1' element. No sign of 'lstSelect' element.
I know I should use a body-parser but don't know how and which one?
This is the Jade template:
extends layout
block content
.jumbotron
h1 Calculator
form(action='/calc',method='post', id="tableForm" )
p
select(name="lstSelect", id="lstSelect", size ="5")
option(value='one') One
option(value='two') Two
option(value='three') Three
p
input(type='text', name='txt1', id='txt1')
p
input(type='submit' name='StdDev', value='StdDev')
This is the NodeJS file:
//"use strict";
var express = require('express');
var routes = require('./routes/index');
var api = require('./routes/api/index');
var http = require('http');
var path = require('path');
var app = express();
var bodyParser = require('body-parser');
var multiparty = require('multiparty');
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
// uncomment after placing your favicon in /public
//app.use(favicon(__dirname + '/public/favicon.ico'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.use(require('stylus').middleware(path.join(__dirname, 'public')));
app.use(express.static(path.join(__dirname, 'public')));
app.post('/calc', function (req, res) {
var lstSelect = req.body.lstSelect; <- undefined
var form = new multiparty.Form();
form.parse(req, function (err, fields, files) {
// fields fields fields
var x = 1; <- bp never reached
});
var b = req.body; <- only txt1 element is here
});
EDIT: big flaw. Selected value is in request.body BUT I still need whole list. I need array of Select box values.
The select doesn't have any option elements, so it's skipped when submitting. The following should fix it;
extends layout
block content
.jumbotron
h1 Calculator
form(action='/calc', method='post', id='tableForm')
p
select(name='lstSelect', id='lstSelect', size='5')
option(value='one') One
option(value='two') Two
option(value='three') Three
p
input(type='text', name='txt1', id='txt1')
p
input(type='submit' name='StdDev', value='StdDev')
Also fixed some indentation so your input elements are inside the paragraphs.
hi I try to get host name in node express js -
i use:
var express = require('express'),
app = express();
var port = process.env.PORT || 3000;
app.use(function(req,res,next){
if (req.hostname == "domain1") {
app.get('/', function(req,res){
res.send('Domain1 is active');
}) else if (req.hostname == "domain2") {
app.get('/', function(req,res){
res.send('Doamin2 is active');
});
}
}
next();
});
app.listen(port);
but its works correct only on the first host - if i change host - I have first result
any advice ?
All requests are showing GET / 404 8.128 ms-13 in console.
I have posted the code below, there is no error in the code. I can run other NodeJS applications. But this is showing 404 in console. It is not even showing the fav icon. It worked once showing Cannot GET / error and the fav icon was visible at that time.
'use strict';
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
var favicon = require('serve-favicon');
var logger = require('morgan');
var port = process.env.PORT || 8001;
var four0four = require('./utils/404')();
var environment = process.env.NODE_ENV;
app.use(favicon(__dirname + '/favicon.ico'));
app.use(bodyParser.urlencoded({extended: true}));
app.use(bodyParser.json());
app.use(logger('dev'));
app.use('/api', require('./routes'));
console.log('About to crank up node');
console.log('PORT=' + port);
console.log('NODE_ENV=' + environment);
switch (environment){
default:
console.log('** DEV **');
app.use(express.static('./src/client/'));
app.use(express.static('./'));
app.use(express.static('./tmp'));
app.use('/app/*', function(req, res, next) {
four0four.send404(req, res);
});
app.use('/*', express.static('./src/client/index.html'));
break;
}
app.listen(port, function() {
console.log('Express server listening on port ' + port);
console.log('env = ' + app.get('env') +
'\n__dirname = ' + __dirname +
'\nprocess.cwd = ' + process.cwd());
});
According to http://expressjs.com/starter/static-files.html I think that your route here app.use('/*', express.static('./src/client/index.html')); will use ./src/client/index.html as the base path and append whatever you provide to find a file. For example
/some-file will look for ./src/client/index.html/some-file which is obviously not existed
In case you want to understand it more, the static middleware use https://github.com/pillarjs/send internally to stream file
So you can do this
app.use('/*', express.static('./src/client'));
It will, by default, set / to src/client/index.html, you can change that behaviour by setting index option as specified here https://github.com/expressjs/serve-static
If you want to redirect /* to ./src/client/index.html do this
// first set the static middleware
app.use('/public', express.static('./src/client'));
// then use redirect
app.get('/*', function(req, res, next){
res.redirect('/public/index.html');
});
This setup will redirect everything to public/index.html. If you want to add APIs or other routes, put it before the app.get('/*')
I have a simple application running on node.js with websockets. This application uses the node-static module for serving some html pages with css, js and so on.
The folder structure is this:
-app
- index.html
- server.js
- img/
- base.png
- sub/
- sub.png
- scripts
- base.js
- sub/
- sub.js
- css
- base.css
- sub/
- sub.css
Where server.js is the server file. Inside server.js there is the following code:
var static = require('node-static');
var http = require('http');
var file = new(static.Server)();
var app = http.createServer(function (req, res) {
file.serve(req, res);
}).listen(process.env.PORT || 1234);
var WebSocketServer = require('websocket').server;
new WebSocketServer({
httpServer: app,
autoAcceptConnections: false
}).on('request', onRequest);
...
Now I need to switch from node-static to Express because I need to use routes. I used this code, however it doesn't work:
var express = require('express');
var app = express();
var http = require('http');
var httpServer = http.Server(app);
app.use(express.static(__dirname+'/app'));
app.get('/', function(req, res){
res.sendfile(__dirname + '/index.html');
});
app.listen(1234);
var WebSocketServer = require('websocket').server;
new WebSocketServer({
httpServer: app,
autoAcceptConnections: false
}).on('request', onRequest);
...
I can serve files, however it breaks the websocket connection.
What's wrong? Please note that the solution should be suitable for working on localhost and Heroku.
I resolved my problem using the following code:
var http = require("http");
var express = require("express");
var app = express();
var port = process.env.PORT || 1234;
app.use(express.static(__dirname + "/"));
var server = http.createServer(app);
server.listen(port);
console.log("http server listening on %d", port);
var WebSocketServer = require('websocket').server;
new WebSocketServer({
httpServer: server,
autoAcceptConnections: false
}).on('request', onRequest);
...
This code is derived from https://devcenter.heroku.com/articles/node-websockets, however my code use the 'websocket' node module instead of 'ws'. Thanks to #Tony for the hint.