I have a nodejs server structured like so:
(app.js):
var fs = require('fs'),
http = require('http'),
https = require('https'),
express = require('express'),
connect = require('express/node_modules/connect'),
app = module.exports = express();
var ssl_options = {
key: fs.readFileSync('/etc/nginx/ssl/server.key'),
cert: fs.readFileSync('/etc/nginx/ssl/server.crt')
};
var server = https.createServer(ssl_options, app);
// EXPRESS
// app.set('view options', { layout: false });
var auth_token = "asdfasfdasdfasdf";
var express_session_id = "express.sid";
app.configure(function () {
app.use(express.cookieParser());
app.use(express.session({secret: auth_token, key: express_session_id}));
app.set("view options", {layout: false});
});
app.get('/', function (req, res) {
console.log (req.headers);
fs.readFile(__dirname + '/index.html', function(err, data){
res.writeHead(200, {'Content-Type': 'text/html'});
res.write(data, 'utf8');
res.end();
});
});
app.listen = function(port) {
server.listen(port);
console_log.log('info', "COTTONMOUTH server listening on port " + port);
};
I have a cluster.js running the above app.js:
var cluster = require('cluster'),
os = require('os'),
workers = {};
if (cluster.isMaster) {
cluster.on('exit', function(worker, code, signal) {
if (worker.suicide === false) {
var exitCode = worker.process.exitCode;
console.error('worker ' + worker.process.pid + ' died ('+exitCode+'). restarting...');
cluster.fork();
}
});
var n = process.env.PROC || os.cpus().length;
for(var i = 0; i < n; i++ ) {
cluster.fork();
}
process.on('SIGTERM', function() {
console.log('[MASTER] Going for shutdown...');
for (var id in cluster.workers) {
console.log('\tkilling worker: ' + cluster.workers[id].process.pid);
cluster.workers[id].destroy();
}
console.log("[MASTER] Here's looking at you, kid.");
});
} else {
require('./app').listen(process.env.PORT || 3456);
}
My problem is that the following setup works fine on my localhost virtual box environment (ubuntu virtual running on a mac host). I am able to access the nodejs server with dev.domain.com:3456.
However, when I move this to my production rackspace server (same environment configs and setup), and try to access it by prod.domain.com:3456
The browser hangs for a bit and returns Error 324 (net::ERR_EMPTY_RESPONSE): The server closed the connection without sending any data.
I did some research and have found some leads but weren't too helpful.
Any Ideas?
UPDATE:
when i lower the port down to 90, it seems to work which is interesting.
I am going to leave it at port 90 for now but if someone has an answer to why this is.
Thanks
I got this error message when my request grew too large (>65K). My solution was to reduce the data into several snippets.
Temporary Workaroud:
when i lower the port down to 90, it seems to work which is interesting. I am going to leave it at port 90 for now but if someone has an answer to why this is.
Thanks
This issue can also be encountered when you add an additional '/' from frontend to call a backend API
For example:
my route is
baseUrl/api/customer
but im sending request to
baseUrl/api/customer/
it will not work, at least this was in my case. Too dumb to notice this.
Maybe this can be helpful to someone
Related
I am not able to run socket.io code in node.js, console.log() is also not displaying when running the code. Below is the code.
app.js
var express = require('express');
var http = require('http');
var app = express();
app.set('port', process.env.PORT || 3000);
app.post('/testStream',test.testStream);
var server = http.createServer(app).listen(app.get('port'), function(){
console.log('Express server listening on port ' + app.get('port'));
});
module.exports.appServer = server;
and I have created a test.js file where I am accessing this exported variable appServer.
var server = require('../app.js');
exports.testStream = function(req,res){
var io = require('socket.io').listen(server.appServer);
io.on('connection',function(socket){
console.log("in socket");
fs.readFile('E:/temp/testimg.png',function(err,buf){
socket.emit('image',{image: true,buffer: buf});
console.log("test image");
});
})
}
when the code runs it stucks and not showing the console.logs(). What I am doing wrong over here. Any help is very much appreciated.
I would suggest following the code structure as suggested in socket.io docs.
Also, you should not be calling io.listen or io.on('connection') inside your testStream express middleware. These are things you should only be doing once, and ideally they should happen during startup, inside app.js and not in reaction to a POST request. In fact, I'm not sure what the purpose of your testStream middleware is, its not even returning any response (eg res.end())
If you want to handle socket connections in a separate module you can, but instead of exporting your app's server the way you are, try passing the io instance as variable to your submodule. In short, try this:
app.js
var app = require('express')();
var server = require('http').Server(app);
var io = require('socket.io')(server);
var test = require('./test')(io);
app.set('port', process.env.PORT || 3000);
server.listen(app.get('port'), function() {
console.log('Express server listening on port ' + app.get('port'));
});
test.js
module.exports = function(io) {
io.on('connection', function(socket) {
console.log("in socket");
fs.readFile('E:/temp/testimg.png', function(err, buf) {
socket.emit('image', {
image: true,
buffer: buf
});
console.log("test image");
});
});
};
I've been bouncing back and forth between socket.io and express.io - but settled for socket.io with Express 4, as I would like to use Namespaces.
I have worked on some examples of having an Express 4 Server using Socket.io - but most examples are based on one file with everything in it. I am trying to separate all my code to make it easier but I am at a loss as to how to add Socket.io (or where).
I have index.js which uses Cluster and basically calls server.js:
var server = require( "./server.js" );
var cluster = require('cluster');
var webApp={
run: function(){
console.log('Starting: Server');
server.listen();
}
};
if(cluster.isMaster){
cluster.fork();
cluster.on('exit',function(worker){
console.log('Worker ' + worker.id + ' died..');
setTimeout( function () { cluster.fork(); }, 1000 );
});
} else{
try {
webApp.run();
}
catch(e)
{
console.log(e);
process.exit(1);
}
process.on('uncaughtException', function(err){
console.log(err);
process.exit(1);
});
process.on( 'SIGINT', function () {
console.log( "\n SIGINT (Crtl-C)" );
//Kill worker
cluster.disconnect();
process.exit(1);
});
}
This then calls the server.js file:
var path = require('path');
var express = require('express');
var bodyParser = require('body-parser');
var config = require('./config/config.js');
var router = require('./routes');
var Server = Object.subClass({
/**
* Constructor
*/
init:function(){
this.appServer = express();
var that = this;
var appServer = this.appServer;
appServer.use(express.static(__dirname + '/public'));
appServer.set('views', path.join(__dirname, 'views'));
appServer.set('view engine', 'ejs');
appServer.use(bodyParser.urlencoded({ extended: true }));
appServer.use(bodyParser.json());
appServer.get('/',router.root);
},
/**
* Listener HTTP
*/
listen:function(){
var port = config.rest.port;
console.log(':: on port:' + port);
this.appServer.listen(port);
}
});
module.exports = new Server();
I am only having one 'route', which is the '/' and is defined in routes.js file. The page loads fine but where do I add the server side socket.io? and do I add any socket.io namespace definitions in the routes.js file or in the javascript of the page being loaded?
There are so many ways of using sockets that I can't seem to work out the best approach for my multi-file approach.
Any help would be brilliant as I seem to be going in circles.
Enjoy our Saturday :)
Thanks again.
I've spent the morning looking at the Cluster/Worker approach and decided to use 'SocketCluster' as it seems to do what I need.
Enjoy your Sunday
i dont know why im getting this error:
this is my code
/*
Chat application for #node.js
express version.
*/
//Load modules.
var express = require('express'),
socket = require('socket.io'),
swig = require('swig'),
fs = require('fs');
//Load config.
console.log('Loading configuration.');
var config = fs.readFileSync('config.json');
var config = JSON.parse(config);
var port = config.port;
var views = config.views;
console.log('Configuration loaded.');
console.log(config);
//Initiate express module in app.
var app = express();
// app.get('/', function(request, response)
// {
// fs.readFile('./views/index.html', function(error, data)
// {
// if(error)
// {
// response.send('View cannot be rendered.');
// }
// response.type('html');
// response.send(data);
// });
// });
var test = "Hello";
app.engine('html', swig.renderFile);
app.set('view engine', 'html');
app.set('views', __dirname + '/views');
swig.setDefaults(
{
cache: false
});
app.get('/', function(request, response)
{
response.render('index',
{
//Var to be named in the render : value;
'test': test,
'Title': 'Testing page',
});
});
//logger.
app.use(function(request, response, next)
{
console.log('%s %s', request.method, request.url);
next();
});
//Set directory for static files (css, js, img)
app.use(express.static(__dirname + '/public'));
//Run the app.
app.listen(port);
it might be some kind of error with the framework itself, but i dont get the clue why, i was using it last night with no error, now im getting this error this morning..
EADDRINUSE means another process is already listening on the same port. Probably this is an earlier run of your server that is still running/crashed and still using the port. Find that process, terminate it, and retry. This is not an error in your javascript code.
Also since you are binding port 80 and running windows, it could be that another web server such as IIS is running and using port 80.
The ports from 0 to 1024 are typically reserved for OS to use. Though its not a thumb rule not to use ports between these limits, its always safe to not use ports in this range to avoid accidental/occassional collision of using port#s.
I've found this script for reading a file an "broadcast" its content to every connection.
var serverServiceConfig={port: 8081};
var express = require("express");
var app = express();
var fs = require('fs');
var socket = require('socket.io');
function readTick(ws){
fs.readFile('tick.json', 'utf8', function (err,data) {
if (!err) {
try {
ws.emit('ticks', data);
} catch (e) {
// handle error
console.log('can not read file');
}
}
});
setTimeout(function () {
readTick(ws);
}, 200);
}
console.log('server is running ...');
app.configure(function(){
app.use(express.static(__dirname + '/'));
});
var server = app.listen(serverServiceConfig.port);
var io = socket.listen(server);
io.sockets.on('connection', function (socket) {
readTick(socket);
socket.on('disconnect', function (socket) {
});
});
The server starts without an error, so far so good. But if i try to connect to the server via ip:port i get the following message:
Cannot GET /
I tested this script on my local machine and it worked (a couple of weeks ago)
From what i "know" or i think is that a route is missing, or?
Any help is more than welcome.
Thank you in advance
Instead of using that function, you should put it in app.get('/', function(){//whatever you want to do//})
I'm doing a little OJT on my first node project and, while I can stand up a simple server, the app is going to get hammered so using cluster seems like a good idea. I've cobbled together some code snippets that I've found in various searches (including SO), but the server won't start. I'm sure my inexperience with node has me doing something stupid, but I don't see it.
var express = require( 'express' );
var cluster = require( 'cluster' );
var path = require( 'path' );
var cCPUs = require( 'os' ).cpus().length;
var port = 3000;
var root = path.dirname( __dirname );
if( cluster.isMaster ) {
for( var i = 0; i < cCPUs; i++ ) {
cluster.fork();
}
cluster.on( 'death', function( worker ) {
console.log( 'Worker ' + worker.pid + ' died.' );
});
}
else {
// eyes.inspect( process.env );
console.log( 'Worker: %s', process.env.NODE_WORKER_ID );
var app = express();
var routes = require( './routes' )( app );
app
.use( cluster.repl( root + 'cluster.repl' ) )
.use( cluster.stats({ connections: true, requests: true }) )
.use( cluster.reload( root ) )
.listen( port );
}
RESULT:
TypeError: Object #<Cluster> has no method 'repl'
If I remove the use calls, the workers start up correctly, but process.env.NODE_WORKER_ID is undefined. Inspecting process.env shows me that it's definitely not defined. Maybe the snippet I used was from an old version, but I'm not sure how to identify the worker thread in any other way.
If anyone can unscrambled whatever I've scrambled, I'd really appreciate it.
For anyone searching later, here's what I ended up with:
const cluster = require('cluster');
const express = require('express');
const path = require('path');
const port = 3000;
const root = path.dirname(__dirname);
const cCPUs = require('os').cpus().length;
if (cluster.isMaster) {
// Create a worker for each CPU
for (let i = 0; i < cCPUs; i++) {
cluster.fork();
}
cluster.on('online', function (worker) {
console.log('Worker ' + worker.process.pid + ' is online.');
});
cluster.on('exit', function (worker, code, signal) {
console.log('worker ' + worker.process.pid + ' died.');
});
} else {
const app = express();
const routes = require('./routes')(app);
app.use(express.bodyParser()).listen(port);
}
I'm still very early in the node learning curve, but the server starts and appears to have a working running on each core. Thanks to JohnnyH for getting me on the right track.
Also take a look at cluster2. It's used by eBay and has an express example
var Cluster = require('cluster2'),
express = require('express');
var app = express.createServer();
app.get('/', function(req, res) {
res.send('hello');
});
var c = new Cluster({
port: 3000,
});
c.listen(function(cb) {
cb(app);
});
Here is my draft of Cluster.js class. Note that we should catch port conflict when you start master process.
/*jslint indent: 2, node: true, nomen: true, vars: true */
'use strict';
module.exports = function Cluster(options, resources, logger) {
var start = function () {
var cluster = require('cluster');
if (cluster.isMaster) {
require('portscanner').checkPortStatus(options.express.port, '127.0.0.1', function (error, status) {
if (status === 'open') {
logger.log.error('Master server failed to start on port %d due to port conflict', options.express.port);
process.exit(1);
}
});
// Each core to run a single process.
// Running more than one process in a core does not add to the performance.
require('os').cpus().forEach(function () {
cluster.fork();
});
cluster.on('exit', function (worker, code, signal) {
logger.log.warn('Worker server died (ID: %d, PID: %d)', worker.id, worker.process.pid);
cluster.fork();
});
} else if (cluster.isWorker) {
var _ = require('underscore');
var express = require('express');
var resource = require('express-resource');
// Init App
var app = express();
// App Property
app.set('port', process.env.PORT || options.express.port);
app.set('views', options.viewPath);
app.set('view engine', 'jade');
app.set('case sensitive routing', true);
app.set('strict routing', false);
// App Middleware
app.use(express.favicon(options.faviconPath));
app.use(express.logger({ stream: logger.stream() }));
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(express.responseTime());
app.use(app.router);
app.use(require('stylus').middleware(options.publicPath));
app.use(express['static'](options.publicPath));
if (options.express.displayError) {
app.use(express.errorHandler());
}
// App Format
app.locals.pretty = options.express.prettyHTML;
// App Route Handler
if (!_.isUndefined(resources) && _.isArray(resources)) {
_.each(resources, function (item) {
if (!_.isUndefined(item.name) && !_.isUndefined(item.path)) {
app.resource(item.name, require(item.path));
}
});
}
// Start Server
var domain = require('domain').create();
domain.run(function () {
require('http').createServer(app).listen(app.get('port'), function () {
logger.log.info('Worker server started on port %d (ID: %d, PID: %d)', app.get('port'), cluster.worker.id, cluster.worker.process.pid);
});
});
domain.on('error', function (error) {
logger.log.error(error.stack);
});
}
};
return {
start: start
};
};