I have a very basic node script that starts up, serving up an html page and finally closes the app (kills the node process ideally). Everything works great except the last line that invokes the close method to tear it down.
var express = require('express')
, http = require('http')
, app = express()
, server = http.createServer(app);
app.get('/', function(req, res) {
res.sendfile(__dirname + '/index.html');
});
app.listen(8090);
console.log("started...");
app.close();
The error I get when I run this w/ node 0.8+ is
app.close();
^
TypeError: Object function app(req, res){ app.handle(req, res); } has no method 'close'
Anyone know how I can more safely close the express app down?
You were so close:
var express = require('express')
, http = require('http')
, app = express()
, server = http.createServer(app);
app.get('/', function(req, res) {
res.sendfile(__dirname + '/index.html');
});
var listener = app.listen(8090);
console.log("started...");
listener.close();
So far the best approach I've found it to kill the node process. seems to get the job done (although for purity I'd like to just close express)
process.exit(code=0)
process.on('SIGTERM', function () {
app.close();
});
Try that
Related
I am trying to follow this tutorial on creating a simple chat application using socket.io. I am at the part of the tutorial where I have to insert all of the code below into a js file and initiate it. I just don't understand why the 2nd of code exist, I heard that express can do a lot more than http. Instead of using the "http.listen" code, can't "app.listen" be used and "app" passed to "io" instead?
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
app.get('/', function(req, res){
res.sendFile(__dirname + '/index.html');
});
io.on('connection', function(socket){
console.log('a user connected');
});
http.listen(3000, function(){
console.log('listening on *:3000');
});
Why do I need to add “require(”http“)” when I already have express?
You don't have to manually load the http module yourself. You use express to create an http server for you (it will load the http module for you) and integrate it with socket.io without manually loading the htttp module like this:
const app = require('express')();
app.get('/', function(req, res){
res.sendFile(__dirname + '/index.html');
});
const server = app.listen(3000, function(){
console.log('listening on *:3000');
});
const io = require('socket.io')(server);
io.on('connection', function(socket){
console.log('a user connected');
});
Internally, app.listen() loads the http module for you, creates a server and then starts it, returning the server object which you can then use with socket.io.
Inside of express, this is the code for app.listen():
const http = require('http');
app.listen = function listen() {
var server = http.createServer(this);
return server.listen.apply(server, arguments);
};
So, somebody had to load the http module. If you use app.listen(), the express will do it for you.
You are right. Express is a framework that sits on top of the nodejs application and provides a much easier,provided more middleware to handle routes, session and cookies and more efficient way to create server as such
var express = require('express');
var app = express();
app.listen(3000);
In this example, for the purpose of creating a socket between different channels, you have to use HTTP to indicate that the socket is used to handle HTTP requests/responses. You simply can't pass an entire express application to io.
Either I have a fundamental misunderstanding of how socket.io works (highly likely), or I am just finding some bug that nobody knows about (nearly impossible).
I've been trying to integrate express with socket.io. On the client side, everything works fine: user clicks button, event emits, everybody's happy.
However, let's say I want to emit this event from within an express route before rendering a page. The event never seems to be emitted. From all the questions on this that I've looked at, I'm supposed to be able to simply plug my "io" instance into my app and then access it from within my routes.
So this is my setup...
// index.js
var app = express();
var port = process.env.PORT || 3700
var io = require('socket.io').listen(app.listen(port));
io.on('connection', function (socket) {
console.log("Socket connected on port " + port)
socket.on('send', function (data) {
console.log("WAFFLES")
});
});
console.log('The magic happens on port ' + port);
require('./app/routes.js')(app, io);
// app/routes.js
module.exports = function(app, io){
app.get('/', function(req, res){
io.on('connection', function (socket) {
console.log("Hello from the route!")
socket.emit('send', {message: 'urdum'})
});
res.render('index')
})
}
So in this instance, I want to be able to go into the / route, see "Hello from the route" and then "WAFFLES" logged to the console after emitting the "send" event. Instead I get absolutely nothing.
I've tried to pass in "io" via app.set('socketio', io). But no matter what, nothing works.
I've also tried emitting the event within the route without the io.on('connection') and simply just doing
io.emit('send' ...)
OR
io.sockets.emit('send' ...)
I have a fundamental misunderstanding of how socket.io works (highly likely)
You are right,
This is typical setup for socket-io, read more in https://socket.io/docs/
// index.js
var express = require('express');
var socketio = require('socket.io');
var http = http = require('http');
var app = express();
// Attach Socket.io
var server = http.createServer(app);
var io = socketio.listen(server);
app.set('socketio', io); // <-- bind socket to app
app.set('server', server); // <-- optional
io.on('connection', function (socket) {
console.log("Socket connected on port " + port);
});
app.listen(3000);
server.listen(3001) // <-- socket port
// app.get('server').listen(3001); // <-- use server or app.get('server')
In your router, access socket by req.app.get('socketio');
// app/routes.js
module.exports = function(app, io){
app.get('/', function(req, res){
var socketio = req.app.get('socketio');
socketio.emit('send', {message: 'urdum'});
res.render('index')
})
}
I need to initialize nowjs on this express server with vhosts.. How do I do that?
var host_api = express()
.get('/', function(req, res){
});
var host_secure = express()
.get('/', function(req, res){
});
express()
.use(vhost('api.domain.com', host_api))
.use(vhost('secure.domain.com', host_secure))
.listen(3000);
Initialize nowjs on simple http
var http = require('http'),
nowjs = require('now');
httpServer = http.createServer(function (req, res) {
res.send('Hello World\n');
});
httpServer.listen(3000);
var everyone = nowjs.initialize(httpServer);
Connect (on which Express is built) includes the required code to run vhosts.
You can see the documentation here: http://www.senchalabs.org/connect/vhost.html
For example:
connect() // Or "app" if app is an express application (see example below)
.use(connect.vhost('foo.com', fooApp))
.use(connect.vhost('bar.com', barApp))
.use(connect.vhost('*.com', mainApp))
Each "app" (fooApp, barApp, mainApp) is either a Node.js HTTP server or a Connect/Express app. You can create each app into a separate js file, and then include it:
var fooApp = require('foo/app.js').app
An example can be seen here: http://www.jondev.net/articles/vHosts_with_Node.JS_and_Express
I would like to use the pretty-error module in my Express app but am having trouble setting it up properly.
I tried using the shortcut...
require('pretty-error').start(function(){
http.createServer(app).listen(app.get('port'), function(){
console.log('Express server listening on port ' + app.get('port'));
});
});
...but it doesn't work.
I haven't used express before, so I'm not sure if this is the best solution, but this is how I integrated pretty-error with express:
// this is app.js
var express = require('express');
var PrettyError = require('pretty-error');
var app = express();
app.get('/', function(req, res) {
// this will throw an error:
var a = b;
});
var server = app.listen(3000, function(){
console.log('Server started \n');
});
// we can now instantiaite Prettyerror
pe = new PrettyError();
// and use it for our app's error handler
app.use(function(err, req, res, next){
console.log(pe.render(err));
});
// we can optionally configure prettyError to simplify the stack trace:
pe.skipNodeFiles(); // this will skip events.js and http.js and similar core node files
This is the screenshot of the error:
You can also add this if you don't want to see those lines about express` core files:
pe.skipPackage('express');
and this is how it'll look like:
Can someone tell me what is going on?
I have an aplication:
var express = require('express')
, http = require('http')
, app = express()
, port = 3000
, mw = require('./lib/middlewareView')
app.use(mw());
app.get('/', function (req, res, next) {
res.send("hello");
});
app.listen(port, function() {
console.log("Listening on " + port);
});
and /lib/middlewareView.js :
module.exports = function middlewareView(){
return function middlewareView(req, res, next) {
console.log("middleware run");
next();
};
};
When I'm using port 3000 and open http://localhost:3000/ everything seems to be fine.
console output:
Listening on 3000
middleware run
hello
But if I switch to port 5000, console prints this:
Listening on 5000
middleware run
hello
middleware run
middleware run
So the middleware runs 3 times during one request, right?
Is it normal?
Its probably to do with favicon.ico - this happens when retrieving the icon for your site, check logs to make sure...