Run same Node.js App on IPV4 and IPV6 simultaneously? - node.js

I know when I have the hostname as "::" this means the same as "0.0.0.0" in IPV4.
const express = require('express')
const app = express()
const port =80
const host6 = "::";
const host4 = "0.0.0.0";
app.get('/', (req, res) => {
res.send('Hello World!')
})
app.listen(port, host6, () => {
console.log(`Example app listening at http://localhost:${port}`)
})
This App should now be accessible through IPV6 but als IPV4. But devices which don't understand IPV6 can not make the initial request over IPV6, so for them the App is not accessible.
How can I run this App on both IP versions on the same Port 80?

Unconfirmed, but I would try to remove the host from the arguments passed to app.listen and only pass the port, app.listen(port).
Express docs for app.listen state that
This method is identical to Node’s http.Server.listen().
Node's documentation for http.Server.listen state that
This method is identical to server.listen() from net.Server.
Node's documentation for net.Server states that
If host is omitted, the server will accept connections on the unspecified IPv6 address (::) when IPv6 is available, or the unspecified IPv4 address (0.0.0.0) otherwise.

Related

Socketio not connecting on postman socket connection ui on localhost

Could not connect to localhost:3000
17:02:53
Error: Unexpected server response: 404
Handshake Details
Request URL: http://localhost:3000/socket.io/?EIO=3&transport=websocket
Request Method: GET
Status Code: 404 Not Found
My express server listen on 3000 port and socketio http on 443 port, i am able to connect socket by hosting this on ec2 instance and using ec2 ip with port number on postman socket connection ui, but on localhost connection always failed with above error on postman socket beta ui.
You need to call listen only once. If you pass your http/https server to express, app.listen() is enough. (except you want to listen on 2 different ports.. For testing, let's call it only once.)
For accessing it on localhost try setting it explicitly with the parameter hostname in app.listen().
Example:
async function startServer() {
const app = express();
const credentials = {key: key, cert: crt};
const httpsServer = createServer(credentials,app);
const io = socketIO(httpsServer);
await require('./loaders').default({ expressApp: app, socketIO: io });
// Let's only call listen once for testing purposes. If you call
// listen on the express app, your https server will automatically listen
// to the same configuration.
// httpsServer.listen(4000);
const port = 3000
const hostname = 'localhost'
// explicitly let the app listen on localhost. If hostname is not
// provided, it will take the first found ipv4 interface
app.listen(port, hostname, err => {
if (err) {
Logger.error(err);
process.exit(1);
return;
}
Logger.info(`
################################################
🛡️ Server listening on https://${hostname}:${port} 🛡️
################################################
`);
});
}
Now you should be able to connect your socket. If it still does not work try
to use http module instead of https for better isolating your problem.
Note that your server now only will be accessible using localhost and not over ip. Both may only be possible when running 2 server instances with different hostnames.
async function startServer() {
const app = express();
const credentials = {key: key, cert: crt};
const httpsServer = createServer(credentials,app);
const io = socketIO(httpsServer);
await require('./loaders').default({ expressApp: app, socketIO: io });
httpsServer.listen(443);
app.listen(config.port, err => {
if (err) {
Logger.error(err);
process.exit(1);
return;
}
Logger.info(`
################################################
🛡️ Server listening on port: ${config.port} 🛡️
################################################
`);
});
}
This is my app.ts file, I am using Ubuntu. so 443 port is not allowed, i changed this port to 4000, now the app listen on the 3000 and socket http server on 4000, but socketio not able to connect with socket url localhost:3000

APP Engine listening to Port 3000 giving 502 Bad Gateway error

I am new to node.js coding. I am learning to build a app I want to host on GCP App engine.
I have created a Node.js code which has hard requirement to listen to port 3000.
const dotenv = require('dotenv').config();
const express = require('express');
const app = express();
const crypto = require('crypto');
const cookie = require('cookie');
const nonce = require('nonce')();
const querystring = require('querystring');
const request = require('request-promise');
const { Console } = require('console');
// const PORT = process.env.PORT || 3000;
const PORT = 3000;
app.get('/', (req, res) => {
res.send('Hello App Engine!');
});
On Yaml file I have specifically added ports to forward.
network:
forwarded_ports:
- 3000/tcp
unless I dont use 8080 port, app engine is failing with 502 Bad Gateway.
Is there a way I can use Port 3000 in App engine.
It works if I change the Port to 8080. But I want this to be at 3000.
I created firewall rules
enter image description here
Nope, you cannot change the default port in GAE.
The forwarded_ports is intended to open access to other services listening on other ports but always there should be something listening on the port 8080.
You can create a dummy service listening in port 8080 and possibly redirect to your app in port 3000. Something else to keep in mind is that when accessing the desired service in port 3000 or any other, this should be specified in the url like https://PROJECT_ID.REGION_ID.r.appspot.com:3000 or more general https://PROJECT_ID.REGION_ID.r.appspot.com:PORT

Are there any specifications on what ports are there for back-end application?

So yesterday I was creating a DockerFile and I noticed that the port we were exposing was 8080 and I understand that Node Web Apps run on 8080. Why 8080??? Can't we use 3000 or 3001? Is it something with Docker or with Node?
const express = require('express');
// Constants
const PORT = 8080;
const HOST = '0.0.0.0';
// App
const app = express();
app.get('/', (req, res) => {
res.send('Hello World');
});
app.listen(PORT, HOST);
You can expose any port or set of ports using EXPOSE in Dockerfile.
EXPOSE 8080 3000 3001
Generally, the Node application uses default port as 3000. But you can change it with configurations.

How to get public Ipv6 with nodejs

I am using nodejs to get ipv4 like
app.get('/getip', (req, res) => {
res.json({
ip: req.headers['x-forwarded-for']
});
});
this work fine for ipv4 but i need to get ipv6 too how can i get public ip of router family ipv6.
I'm using node 7.6.0
This code doesn't get an IPv4 or IPv6 address. It gets the value of the X-Forwarded-For header provided by some frontend server in front of your application. If that server doesn't accept an IPv6 connection, there will be no IPv6 address.
Use this code to fetch User's IPv6 Remote address
const express = require("express");
const bodyParser = require("body-parser");
const app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.get("/", (req, res) => res.json({
ip: req.ip || req.connection.remoteAddress || 'null',
}));
const listenServer = () => {
console.log('App running on');
};
// Use IPv4 address to listen on IPv4
app.listen(3000, '0.0.0.0', listenServer);
// Use IPv6 address to listen on IPv6.
app.listen(3000, '2401:4900:169e:80c3:11e9:63ba:1f81:d224', listenServer);

nodejs v5.10.1 cannot get my host address anymore?

Why the latest version of nodejs (v5.10.1) cannot get my host address anymore?
express code:
var express = require('express');
var app = express();
// respond with "Hello World!" on the homepage
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(server.address());
console.log('Example app listening at http://%s:%s', host, port);
});
result:
{ address: '::', family: 'IPv6', port: 3000 }
Example app listening at http://:::3000
It should be:
http://127.0.0.1
Any ideas how I can fix this?
I am on Linux.
Actually, maybe you will see something like
:80
and then
::80
actually this one have a pattern like this:
host:port IPv4
host::port IPv6
127.0.0.1:80 means that using IPv4, listening in 127.0.0.1 in port 80
:80 means that using IPv4 ,listening on all address in port 80
127.0.0.1::80 means that using IPv6, listening in 127.0.0.1 in port 80
and so on.
so, the ::3000 means listening to IPv6 in port 3000
These configuration was done under these variable
var host = server.address().address;
var port = server.address().port;
you can just change the value of these variable to "127.0.0.1" and "80" and see what happens, but most likely your machine still using IPv6 there, if you want to change to IPv4 for your machine, change the setting of your machine under:
Windows: control panel -> network and sharing center -> (your network) -> properties -> setup the IPv4
Linux: i dont have linux machine to test this, but the syntax should be using ifconfig or ipconfig depends on your linux, please refer for something like https://unix.stackexchange.com/questions/34093/static-ipv4-ipv6-configuration-on-centos-6-2
Mac: i dont have mac machine also, should be the same with linux so try to do the same also
I have the same problem, i solved it acessing like an array:
server.address()["port"]
Here a example:
export const onError = (server: Server) => {
console.log(server.address()["port"])
return (error: NodeJS.ErrnoException): void => {
let port: number | string = server.address()["port"];
if (error.syscall !== 'listen') throw error;
let bind = (typeof port === 'string') ? `pipe ${port}` : `port ${port}`;
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;
}
}
}

Resources