You often see example hello world code for Node that creates an Http Server, starts listening on a port, then followed by something along the lines of:
console.log('Server is listening on port 8000');
But ideally you'd want this instead:
console.log('Server is listening on port ' + server.port);
How do I retrieve the port the server is currently listening on without storing the number in a variable prior to calling server.listen()?
I've seen this done before but I can't find it in the Node documentation. Maybe it's something specific to express?
Express 4.x answer:
Express 4.x (per Tien Do's answer below), now treats app.listen() as an asynchronous operation, so listener.address() will only return data inside of app.listen()'s callback:
var app = require('express')();
var listener = app.listen(8888, function(){
console.log('Listening on port ' + listener.address().port); //Listening on port 8888
});
Express 3 answer:
I think you are looking for this(express specific?):
console.log("Express server listening on port %d", app.address().port)
You might have seen this(bottom line), when you create directory structure from express command:
alfred#alfred-laptop:~/node$ express test4
create : test4
create : test4/app.js
create : test4/public/images
create : test4/public/javascripts
create : test4/logs
create : test4/pids
create : test4/public/stylesheets
create : test4/public/stylesheets/style.less
create : test4/views/partials
create : test4/views/layout.jade
create : test4/views/index.jade
create : test4/test
create : test4/test/app.test.js
alfred#alfred-laptop:~/node$ cat test4/app.js
/**
* Module dependencies.
*/
var express = require('express');
var app = module.exports = express.createServer();
// Configuration
app.configure(function(){
app.set('views', __dirname + '/views');
app.use(express.bodyDecoder());
app.use(express.methodOverride());
app.use(express.compiler({ src: __dirname + '/public', enable: ['less'] }));
app.use(app.router);
app.use(express.staticProvider(__dirname + '/public'));
});
app.configure('development', function(){
app.use(express.errorHandler({ dumpExceptions: true, showStack: true }));
});
app.configure('production', function(){
app.use(express.errorHandler());
});
// Routes
app.get('/', function(req, res){
res.render('index.jade', {
locals: {
title: 'Express'
}
});
});
// Only listen on $ node app.js
if (!module.parent) {
app.listen(3000);
console.log("Express server listening on port %d", app.address().port)
}
In express v3.0,
/* No longer valid */
var app = express.createServer();
app.listen();
console.log('Server running on %s', app.address().port);
no longer works! For Express v3.0, you should create an app and a server this way:
var express = require('express');
var http = require('http');
var app = express();
var server = http.createServer(app);
app.get('/', function(req, res) {
res.send("Hello World!");
});
server.listen(3000);
console.log('Express server started on port %s', server.address().port);
I ran in to this issue myself and wanted to document the new syntax. This and other changes in Express v3.0 are visible at https://github.com/visionmedia/express/wiki/Migrating-from-2.x-to-3.x
In case when you need a port at the time of request handling and app is not available, you can use this:
request.socket.localPort
In the current version (v0.5.0-pre) the port seems to be available as a property on the server object, see http://nodejs.org/docs/v0.4.7/api/net.html#server.address
var server = http.createServer(function(req, res) {
...
}
server.listen(8088);
console.log(server.address());
console.log(server.address().address);
console.log(server.address().port);
outputs
{ address: '0.0.0.0', port: 8088 }
0.0.0.0
8088
I use this way Express 4:
app.listen(1337, function(){
console.log('Express listening on port', this.address().port);
});
By using this I don't need to use a separate variable for the listener/server.
If you're using express, you can get it from the request object:
req.app.settings.port // => 8080 or whatever your app is listening at.
Requiring the http module was never necessary.
An additional import of http is not necessary in Express 3 or 4. Assigning the result of listen() is enough.
var server = require('express')();
server.get('/', function(req, res) {
res.send("Hello Foo!");
});
var listener = server.listen(3000);
console.log('Your friendly Express server, listening on port %s', listener.address().port);
// Your friendly Express server, listening on port 3000
Again, this is tested in Express 3.5.1 & 4.0.0. Importing http was never necessary. The listen method returns an http server object.
https://github.com/visionmedia/express/blob/master/lib/application.js#L531
req.headers.host.split(':')[1]
If you did not define the port number and you want to know on which port it is running.
let http = require('http');
let _http = http.createServer((req, res) => {
res.writeHead(200);
res.end('Hello..!')
}).listen();
console.log(_http.address().port);
FYI, every time it will run in a different port.
With latest node.js (v0.3.8-pre): I checked the documentation, inspected the server instance returned by http.createServer(), and read the source code of server.listen()...
Sadly, the port is only stored temporarily as a local variable and ends up as an argument in a call to process.binding('net').bind() which is a native method. I did not look further.
It seems that there is no better way than keeping a reference to the port value that you provided to server.listen().
The simplest way to convert from the old style to the new (Express 3.x) style is like this:
var server = app.listen(8080);
console.log('Listening on port: ' + server.address().port);
Pre 3.x it works like this:
/* This no longer works */
app.listen(8080);
console.log('Listening on port: ' + app.address().port);
You can get the port number by using server.address().port
like in below code:
var http = require('http');
var serverFunction = function (req, res) {
if (req.url == '/') {
console.log('get method');
res.writeHead(200, { 'content-type': 'text/plain' });
res.end('Hello World');
}
}
var server = http.createServer(serverFunction);
server.listen(3002, function () {
console.log('server is listening on port:', server.address().port);
});
var express = require('express');
var app = express();
app.set('port', Config.port || 8881);
var server = app.listen(app.get('port'), function() {
console.log('Express server listening on port ' + server.address().port);
});
Express server listening on port 8881
I was asking myself this question too, then I came Express 4.x guide page to see this sample:
var server = app.listen(3000, function() {
console.log('Listening on port %d', server.address().port);
});
The findandbind npm addresses this for express/restify/connect: https://github.com/gyllstromk/node-find-and-bind
const express = require('express');
const morgan = require('morgan')
const PORT = 3000;
morgan.token('port', (req) => {
return req.app.locals.port;
});
const app = express();
app.locals.port = PORT;
app.use(morgan(':method :url :port'))
app.get('/app', function(req, res) {
res.send("Hello world from server");
});
app1.listen(PORT);
You might be looking for process.env.PORT. This allows you to dynamically set the listening port using what are called "environment variables". The Node.js code would look like this:
const port = process.env.PORT || 3000;
app.listen(port, () => {console.log(`Listening on port ${port}...`)});
You can even manually set the dynamic variable in the terminal using export PORT=5000, or whatever port you want.
express v4+
const app = require("express")();
app.listen( 5555, function() {
console.log( this.address().port )
})
The easier way is just to call app.get('url'), which gives you the protocol, sub domain, domain, and port.
Related
I'm trying to understand the connection between Node.js and Express.
My Code for creating a Node.js Server:
const https = require('https');
const fs = require('fs');
const options = {
key: fs.readFileSync('./https1/key.pem'),
cert: fs.readFileSync('./https1/cert.pem')
};
const server = https.createServer(options, function(req,res){
res.writeHead(200);
res.end(`Hello world!!!!!!!!!!! \n`);
});
server.listen(3000, function(){
console.log('Server listening on port 3000 \n');
});
I run a curl operation curl -k localhost:3000 and it gives me a "Hello World" Output
My code for creating an Express Server:
// call the packages we need
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
var port = process.env.PORT || 8080;
// ROUTES FOR OUR API
var router = express.Router();
// test route to make sure everything is working (accessed at GET http://localhost:8080/api)
router.get('/', function(req, res) {
res.json({ message: 'hooray! welcome to our api!' });
});
app.listen(port);
console.log('Magic happens on port ' + port);
Is it possible for us to mix both of these?
To be more specific, I would like to create my Server using the Node.js way, but create my routes using the Express way. Can I do it or should I just follow one methodology? What is the connection between Node.js and Express? I understand that Express is just a framework for Node.js but where exactly does the deviation occurs if at all any?
Can I mix and combine the two when required?
Thank you
Yes you can combine nodejs and express, but not encourage you to combine those unless you have specific purpose such as using AWS lambda or making specific OS tasks that has to be made only with pure node.
As you already know, express is just a framework. You can write code more shortly using express.
For example, to make the browser displaying Hello world,
// nodejs version
const http = require('http');
const hostname = '127.0.0.1';
const port = 3000;
const server = http.createServer((req, res) => {
res.statusCode = 200;
res.setHeader('Content-Type', 'text/plain');
res.end('Hello World!\n');
});
server.listen(port, hostname, () => {
console.log(`Server running at http://${hostname}:${port}/`);
});
// express version
const express = require('express');
const app = express();
const port = 3000;
app.listen(port, (req, res) => {
res.send('Hello World!\n');
})
More easier, and intuitive.
You surely can that's the way to create a Secure HTTPS server with express and followed in most projects
const https = require('https');
const express = require('express');
const app = express();
const options = {
key: fs.readFileSync('./https1/key.pem'),
cert: fs.readFileSync('./https1/cert.pem')
};
const server = https.createServer(options, app);
app.get('/', (req, res) => {
res.send('hello world')
}
server.listen(config.port, () => {
console.log(`Express server listening on port ${port} in ${app.get('env')} mode`);
});
Now add your routes and all.
I'm trying to teach myself socket.io and node.js by following this tutorial: https://www.youtube.com/watch?v=tzNOqcoupWQ
This is the code that's written by the end of the turotial:
const express = require('express');
const app = express();
const server = require('http').Server(app);
const io = require('socket.io')(server);
const path = require('path');
const port = process.env.Port || 3000;
app.use(express.static(path.join(__dirname, 'public')));
app.set('view engine', 'ejs');
app.get('/', function(req, res){
res.sendFile(__dirname + '/index.html');
})
server.listen(port, function(){
console.log('Listening on port ' + port);
io.on('connection', function(socket){
console.log('User Connected! :)');
//handle a new message
socket.on('new:message', function(msgObj){
io.emit('new:message', msgObj);
});
//handle a new member joining
socket.on('new:member', function(name){
io.emit('new:member', name);
});
})
});
The problem is, it seems the io.on('connection' method isn't going through and the "User connected!" message isn't being printed out to the console, yet my index.html loads up just fine (it's just a simple header for now).
What can I do to solve this?
[EDIT]
Here's the index.html
<h1>Hello, World!</h1>
You might need to include the client side socket. i.e add the below code in your html file being served.
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io();
</script>
Integrating Socket.IO in the documentation is a good place to start.
I am specify port 30000, but the app ends up listening on a different port.
This is the code I am using:
var express = require('express');
var bodyParser = require('body-parser');
var path = require('path');
var app = express();
app.get('/', function(req, res) {
res.send('Hello World');
});
app.listen(30000, function() {
console.log('Server started on port %d', app.listen().address().port);
});
The port the app is listening to gets set to a different value when it runs. If I use the value that it logs to the console in the browser, it works properly.
Thanks much!
You run app.listen() twice - the second time in the argument to console.log.
The second one has no port as argument so it chooses a random port.
Change this:
app.listen(30000, function() {
console.log('Server started on port %d', app.listen().address().port);
});
to:
var listener = app.listen(30000, function () {
console.log('Server started on port %d', listener.address().port);
});
I'm trying to modularize my application files and I'm having problems with Socket.io. I would like to use the io inside my routes.js. Something like this:
var router = require('express').Router();
var io = require('./sockets/my-io');
router.get('/', function(req, res) {
io.emit('request-detected');
});
module.exports = router;
But I can't do, because the socket.io needs the app server, and when I'm inside the routes.js file, the app server is not listening or being exported yet.
Can you give me a solution, or any other approach to this problem?
Here's what I have, and if it's possible, I would like to keep the file structure:
app.js
var app = require('express')();
var routes = require('./routes');
/* ... */
app.use('/contacts', routes);
module.exports = app;
bin/www
#!/usr/bin/env node
var app = require('../wallet');
var server = app.listen(port, function() {
debug('Express is listening o port ' + port);
});
routes.js
var router = require('express').Router();
router.get('/', function(req, res) {
console.log('hey');
});
module.exports = router;
You can do it by passing the io variable to your routes module.
bin/www
#!/usr/bin/env node
var app = require('./app');
var server = app.listen(3000, function() {
console.log('Express is listening on port 3000');
}); // start the server
var socket = require('./socket')(server); // require socket.io code
var routes = require('./routes')(socket); // require routes
app.use('/', routes);
app.js
var express = require('express');
var app = express();
app.use(express.static(__dirname + '/public'));
app.set('views engine', 'ejs');
app.set('views', __dirname + '/');
module.exports = app;
socket.js
var socketio = require('socket.io');
function init(server) {
var io = socketio(server);
io.on('connection', function (socket) {
console.log("socket connected");
socket.on('newEvent', function (data) {
console.log(data);
});
});
return io;
}
module.exports = init;
routes.js
var express = require('express');
var route = express.Router();
function init(io) {
route.get('/', function (req, res) {
res.render('index.ejs', {});
setTimeout(function() {io.emit('newEvent', {message: "Hi from the server"})}, 2000);
});
return route;
}
module.exports = init;
The code above worked for me. However, I'm not sure why you want to do that.
Inside the router, you still have full control of what you want to send to the user via html, so you can just add the data to the html directly.
The idea of socket.io is that you can send data between the client and back once he has loaded the html and established a connection to your server with socket.io.
As you can see in the routes.js, I had to add a timeout to the emit. This is because the socket event will be emit before the browser has reloaded the page. In my case the browser logged the event and then immediately refreshed, losing the data you just sent.
Another problem is that you don't know anything about the socket of the client that is requesting the page because he hasn't connected yet. This means that calling io.emit() will send the event to all connected sockets.
As I said, this really depends on what exactly you want to do.
EDIT:
Instead of updating your contacts using ajax, you can do that with socket.io.
socket.js
var socketio = require('socket.io');
function init(server) {
var io = socketio(server);
io.on('connection', function (socket) {
console.log("socket connected");
socket.on('newContact', function (data, callback) {
// add data.contactName to db
// after adding something, you use the callback to
// send the added data back to the client
// callback(newContact);
});
});
return io;
}
module.exports = init;
index.html
<script type="text/javascript" >
var socket = io();
// call this emit when the user wants to add a contact
socket.emit('newContact', {contactName: name}, function(newContact) {
// here you will get the result from the server and you can
// update the html with jquery for example
});
</script>
If i understand your question correctly ,maybe you can try this way.
in your routes.js file
var app = require('./app');
var server = require('http').createServer(app);
var io = require('./sockets/my-io')(server);
var route = app.Router();
in your app.js file
var port = process.env.PORT || 3000;
app.listen(port,function(){
console.log('server on port ' + port)
})
I am working on a single page web app using Node + Express and Handlebars for templating. Everything currently works well from index.html, which is served from a pretty standard server.js file:
var express = require('express');
var server = express();
server.use(express.static(__dirname + '/public'));
var port = 10001;
server.listen(port, function() {
console.log('server listening on port ' + port);
});
This works perfectly when loading from http://localhost:10001/. My issue is that I'm using push states in the app, so the browser may show a URL like http://localhost:10001/foo/bar and then if I refresh the page, I get the error Cannot GET /foo/bar since there is no route for this.
So my question, and pardon my incredible noobishness when it comes to Node, can I make it so all requests route to index.html? The JavaScript in my app can handle showing the right content based on URL params on page load. I don't want to define custom routes as the number would be large, and the paths for them can change dynamically.
const express = require('express')
const server = express()
/* route requests for static files to appropriate directory */
server.use('/public', express.static(__dirname + '/static-files-dir'))
/* other routes defined before catch-all */
server.get('/some-route', (req, res) => {
res.send('ok')
})
/* final catch-all route to index.html defined last */
server.get('/*', (req, res) => {
res.sendFile(__dirname + '/index.html');
})
const port = 8000;
server.listen(port, function() {
console.log('server listening on port ' + port)
})
This pattern will serve static assets before hitting the catch-all route that serves up your front-end application. To register any additional routes, just add them above the catch-all route.
var express = require('express');
var server = express();
// middleware
server.use(express.static(__dirname + '/public'));
// routes
server.use('*', function (req, res) {
// serve file
});
var port = 10001;
server.listen(port, function() {
console.log('server listening on port ' + port);
});
This short thing works well:
import express from "express";
const app = express(),
staticServe = express.static(`${ __dirname }/public`);
app.use("/", staticServe);
app.use("*", staticServe);
Just make sure that all URLs from your HTML/JS files are absolute now, as all resources that do not exist will return index.html file.
Express v 4.15.2
var app = express();
var options = {
dotfiles: 'ignore',
etag: true,
extensions: ['htm', 'html'],
index: 'index.html',
lastModified: true,
maxAge: '1d',
setHeaders: function (res, path, stat) {
res.set('x-timestamp', Date.now());
res.header('Cache-Control', 'public, max-age=1d');
}
};
app.use(compression());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.use(methodOverride());
app.use('/', express.static(__dirname + '/public', options));
app.use('*', express.static(__dirname + '/public', options));
var express = require('express');
var server = express();
server.use(express.static(__dirname + '/public'));
server.get('*', function(req, res){
res.sendFile('index.html');
});
var port = 10001;
server.listen(port, function() {
console.log('server listening on port ' + port);
});