On the socket.io web page, Get Started: Chat application, located here:
http://socket.io/get-started/chat/
there is this code:
var app = require('express')();
var http = require('http').Server(app);
which could be rewritten a little more clearly like this:
var express = require('express');
var http = require('http');
var app = express();
var server = http.Server(app);
The socket.io example uses http.Server() to create a server. Yet, the express docs for app.listen() show an example where the server is created using http.createServer(app):
app.listen()
Bind and listen for connections on the given host and port. This
method is identical to node's http.Server#listen().
var express = require('express');
var app = express();
app.listen(3000);
The app returned by express() is in fact a JavaScript Function,
designed to be passed to node's HTTP servers as a callback to handle
requests. This allows you to provide both HTTP and HTTPS versions of
your app with the same codebase easily, as the app does not inherit
from these (it is simply a callback):
var express = require('express');
var https = require('https');
var http = require('http');
var app = express();
http.createServer(app).listen(80);
https.createServer(options, app).listen(443);
The app.listen() method is a convenience method for the following (if
you wish to use HTTPS or provide both, use the technique above):
app.listen = function(){
var server = http.createServer(this);
return server.listen.apply(server, arguments);
};
What's the difference between http.createServer(app) and http.Server(app)?? The http docs are no help.
There is no difference. http.createServer() only does one thing: it calls http.Server() internally and returns the resulting instance.
Related
This may be a very basic question but I simply don't get it. What is the difference between creating an app using Express.js and starting the app listening on port 1234, for example:
var express = require('express');
var app = express();
//app.configure, app.use etc
app.listen(1234);
and adding an http server:
var express = require('express');
var http = require('http');
var app = express();
var server = http.createServer(app);
//app.configure, app.use etc
server.listen(1234);
What's the difference?
If I navigate to http://localhost:1234, thus I get the same output.
The second form (creating an HTTP server yourself, instead of having Express create one for you) is useful if you want to reuse the HTTP server, for example to run socket.io within the same HTTP server instance:
var express = require('express');
var app = express();
var server = require('http').createServer(app);
var io = require('socket.io').listen(server);
...
server.listen(1234);
However, app.listen() also returns the HTTP server instance, so with a bit of rewriting you can achieve something similar without creating an HTTP server yourself:
var express = require('express');
var app = express();
// app.use/routes/etc...
var server = app.listen(3033);
var io = require('socket.io').listen(server);
io.sockets.on('connection', function (socket) {
...
});
There is one more difference of using the app and listening to http server is when you want to setup for https server
To setup for https, you need the code below:
var https = require('https');
var server = https.createServer(app).listen(config.port, function() {
console.log('Https App started');
});
The app from express will return http server only, you cannot set it in express, so you will need to use the https server command
var express = require('express');
var app = express();
app.listen(1234);
Just for punctuality purpose and extend a bit Tim answer.
From official documentation:
The app returned by express() is in fact a JavaScript Function,
DESIGNED TO BE PASSED to Node’s HTTP servers as a callback to handle
requests.
This makes it easy to provide both HTTP and HTTPS versions of your
app with the same code base, as the app does not inherit from these
(it is simply a callback):
var https =require('https');
var http = require('http');
http.createServer(app).listen(80);
https.createServer(options, app).listen(443);
The app.listen() method returns an http.Server object and (for HTTP)
is a convenience method for the following:
app.listen = function() {
var server = http.createServer(this);
return server.listen.apply(server, arguments);
};
I came with same question but after google, I found there is no big difference :)
From Github
If you wish to create both an HTTP and HTTPS server you may do so with the "http" and "https" modules as shown here.
/**
* Listen for connections.
*
* A node `http.Server` is returned, with this
* application (which is a `Function`) as its
* callback. If you wish to create both an HTTP
* and HTTPS server you may do so with the "http"
* and "https" modules as shown here:
*
* var http = require('http')
* , https = require('https')
* , express = require('express')
* , app = express();
*
* http.createServer(app).listen(80);
* https.createServer({ ... }, app).listen(443);
*
* #return {http.Server}
* #api public
*/
app.listen = function(){
var server = http.createServer(this);
return server.listen.apply(server, arguments);
};
Also if you want to work with socket.io see their example
See this
I prefer app.listen() :)
Express is basically a wrapper of http module that is created for the ease of the developers in such a way that..
They can set up middlewares to respond to HTTP Requests (easily) using express.
They can dynamically render HTML Pages based on passing arguments to templates using express.
They can also define routing easily using express.
I am pretty new to nodejs and very new to socket.io and express. I have some code that is working, but am having trouble understanding exactly why it's working.
My question for the below code is how does the express app know to listen on port 80? There's a server.listen. But there is no app.listen in the code. Yet app.post() readily accepts posted data.
Please consider the following code
var https = require('https');
var url = require('url');
var fs = require('fs');
var bodyParser = require('body-parser');
var express = require('express');
var app = express();
//var io = require('socket.io');
var zlib = require('zlib');
app.use(bodyParser.urlencoded({extended: true }));
var options = {
key: fs.readFileSync('my.key'),
cert: fs.readFileSync('my.crt')
};
var serverPort = 80;
var server = https.createServer(options, app);
var io = require('socket.io')(server);
// log when the server is ready
server.listen(serverPort, function() {
console.log('Web socket server up and running at port %s', serverPort);
// this prints 80, as expected
});
app.post('/api', function (req, res) {
// working code is in here that receives the post variables and responds
}
With Express, the app object is just a request handler for some http server. If you call app.listen(), then the app object will create an http server for you. But, if you have created your own http server (which your code example does), then the app object just becomes a request listener on that server with this line of your code:
var server = https.createServer(options, app);
That creates the http server and registers app as a request listener (so it sees all incoming requests). This allows the Express app object to then process the routes that are registered with it to server routes like app.get(...) or app.post(...).
And, the port for Express is the port for the http server so it's the port that was used when the http server was created. What's important to understand here is that Express is not its own server. It's just a request listener for some http server.
In your code example, your http server is set up for port 80 so that's the port being used and Express gets registered as a request handler on all those incoming http requests on that port.
If you look at the source code for app.listen(), you see this:
app.listen = function listen() {
var server = http.createServer(this);
return server.listen.apply(server, arguments);
};
All, it does is create an http server with the app object as a listener and then call .listen() on that new server.
the app does not have to know on which port to listen. Basically, server is your HTTP server binding which listens on port 80 in your example. var server = https.createServer(options, app); then tells the server to listen on port 80 for HTTP requests and forward them to your app. The app then does the routing stuff that links the function you sepcified with app.post(...) to a specific request URL (/api in this case).
TL;DR: The app does not need to listen, because the server is the only communication interface to the outside.
var app, certificate, credentials, express, fs, http, httpServer, https, httpsServer, privateKey;
fs = require('fs');
http = require('http');
https = require('https');
privateKey = fs.readFileSync('key.pem', 'utf8');
console.log(privateKey);
certificate = fs.readFileSync('cert.pem', 'utf8');
console.log(certificate);
credentials = {
key: privateKey,
cert: certificate
};
express = require('express');
app = express();
httpServer = http.createServer(app);
httpsServer = https.createServer(credentials, app);
httpServer.listen(80);
httpsServer.listen(443);
I am on OS X and I have confirmed nothing else is listening on 80 and 443. I run this as sudo and when I go http://127.0.0.1, it works. However, when I go to https://127.0.0.1, I get not found.
What am I doing incorrect?
To enable your app to listen for both http and https on ports 80 and 443 respectively, do the following
Create an express app:
var express = require('express');
var app = express();
The app returned by express() is a JavaScript function. It can be be passed to Node’s HTTP servers as a callback to handle requests. This makes it easy to provide both HTTP and HTTPS versions of your app using the same code base.
You can do so as follows:
var express = require('express');
var https = require('https');
var http = require('http');
var fs = require('fs');
var app = express();
var options = {
key: fs.readFileSync('/path/to/key.pem'),
cert: fs.readFileSync('/path/to/cert.pem')
};
http.createServer(app).listen(80);
https.createServer(options, app).listen(443);
For complete detail see the doc
add the following line of code:
app.listen(443);
Also, try getting rid of all of the http module, as express handles most of that for you. Look at the beginning Hello World for Express, http://expressjs.com/starter/hello-world.html and look for the part where it handles the port.
I have discovered that there are at least 2 ways to go about doing this. The first way creates an HTTP server, although the 2nd way doesn't.
I am not able to find any concrete tutorial regarding this.
Case I
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
http.listen(3000);
Case II
var app = require('express')();
var port = process.env.PORT || 3000;
var io = require('socket.io').listen(app.listen(port));
How are the two methods different? And why doesn't the second method require an HTTP server?
app.listen() creates the http server for you (a shortcut that express lets you use).
Here's the code for app.listen():
app.listen = function(){
var server = http.createServer(this);
return server.listen.apply(server, arguments);
};
This Express code is here.
What's the meaning of passing express object to http object in this example?
var express = require('express');
var app = express();
var http = require('http').Server(app);
var io = require('socket.io')(http);
Many examples do this. I don't quite know what it means.
Some other examples don't use http at all. Here's example from Express.js website (http://expressjs.com/starter/hello-world.html), and it doesn't use http object:
var express = require('express')
var app = express()
app.get('/', function (req, res) {
res.send('Hello World!')
})
var server = app.listen(3000, function () {
var host = server.address().address
var port = server.address().port
console.log('Example app listening at http://%s:%s', host, port)
})
Is there any difference at all? Does the second example still use http somehow? Or does it use express's own http server?
In the first example, the http module's Server method is being called, which is effectively an alias for createServer. You can see the relevant line here. The argument is essentially a function which accepts parameters request, response as expected of a requestListener.
In the second example, Express already requires http in its own module, so it is not necessary for the user to require it explicitly.
The main difference is that you are creating an instance of http.Server by yourself in the former, while Express creates a server instance for you in the latter. Instantiating a server by yourself is necessary if you wish to use the https module instead of http.